This commit is contained in:
Valdis Bogdāns 2026-04-06 04:01:17 +08:00 committed by GitHub
commit 61b3a131dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 12932 additions and 627 deletions

4
.gitmodules vendored
View File

@ -119,6 +119,10 @@
[submodule "externals/aacdec/fdk-aac"]
path = externals/aacdec/fdk-aac
url = https://android.googlesource.com/platform/external/aac
[submodule "externals/freetype"]
path = externals/freetype
url = https://github.com/freetype/freetype.git
shallow = true
[submodule "externals/CLI11"]
path = externals/CLI11
url = https://github.com/shadexternals/CLI11.git

View File

@ -486,8 +486,12 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
src/core/libraries/web_browser_dialog/webbrowserdialog.h
src/core/libraries/font/font.cpp
src/core/libraries/font/font.h
src/core/libraries/font/font_internal.cpp
src/core/libraries/font/font_internal.h
src/core/libraries/font/fontft.cpp
src/core/libraries/font/fontft.h
src/core/libraries/font/fontft_internal.cpp
src/core/libraries/font/fontft_internal.h
src/core/libraries/font/font_error.h
)
@ -1137,7 +1141,7 @@ add_executable(shadps4
create_target_directory_groups(shadps4)
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG freetype)
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 SDL3_mixer::SDL3_mixer pugixml::pugixml)
target_link_libraries(shadps4 PRIVATE stb::headers lfreist-hwinfo::hwinfo nlohmann_json::nlohmann_json miniz::miniz fdk-aac CLI11::CLI11 OpenAL::OpenAL Cpp_Httplib)

View File

@ -56,6 +56,16 @@ if (NOT TARGET ZLIB::ZLIB)
set(ZLIB_INCLUDE_DIRS "${FETCHCONTENT_BASE_DIR}/zlib-build")
endif()
# FreeType
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/freetype/CMakeLists.txt" AND NOT TARGET freetype)
# Keep optional deps off to reduce build surface; zlib stays enabled for compressed fonts.
set(FT_DISABLE_BZIP2 ON CACHE BOOL "" FORCE)
set(FT_DISABLE_BROTLI ON CACHE BOOL "" FORCE)
set(FT_DISABLE_HARFBUZZ ON CACHE BOOL "" FORCE)
set(FT_DISABLE_PNG ON CACHE BOOL "" FORCE)
add_subdirectory(freetype)
endif()
# SDL3
if (NOT TARGET SDL3::SDL3)
set(SDL_TEST_LIBRARY OFF)

1
externals/freetype vendored Submodule

@ -0,0 +1 @@
Subproject commit b91f75bd02db43b06d634591eb286d3eb0ce3b65

File diff suppressed because it is too large Load Diff

View File

@ -1,299 +1,589 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Font {
struct OrbisFontTextCharacter {
// Other fields...
struct OrbisFontTextCharacter* next; // Pointer to the next node 0x00
struct OrbisFontTextCharacter* prev; // Pointer to the next node 0x08
void* textOrder; // Field at offset 0x10 (pointer to text order info)
u32 characterCode; // Field assumed at offset 0x28
u8 unkn_0x31; // Offset 0x31
u8 unkn_0x33; // Offset 0x33
u8 charType; // Field assumed at offset 0x39
u8 bidiLevel; // Field assumed at offset 0x3B stores the Bidi level
u8 formatFlags; // Field at offset 0x3D (stores format-related flags)
};
struct OrbisFontRenderSurface {
void* buffer;
s32 widthByte;
s8 pixelSizeByte;
u8 unkn_0xd;
u8 styleFlag;
u8 unkn_0xf;
s32 width, height;
u32 sc_x0;
u32 sc_y0;
u32 sc_x1;
u32 sc_y1;
void* unkn_28[3];
};
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;
};
s32 PS4_SYSV_ABI sceFontAttachDeviceCacheBuffer();
s32 PS4_SYSV_ABI sceFontBindRenderer();
s32 PS4_SYSV_ABI sceFontCharacterGetBidiLevel(OrbisFontTextCharacter* textCharacter,
int* bidiLevel);
s32 PS4_SYSV_ABI sceFontCharacterGetSyllableStringState();
s32 PS4_SYSV_ABI sceFontCharacterGetTextFontCode();
s32 PS4_SYSV_ABI sceFontCharacterGetTextOrder(OrbisFontTextCharacter* textCharacter,
void** pTextOrder);
u32 PS4_SYSV_ABI sceFontCharacterLooksFormatCharacters(OrbisFontTextCharacter* textCharacter);
u32 PS4_SYSV_ABI sceFontCharacterLooksWhiteSpace(OrbisFontTextCharacter* textCharacter);
OrbisFontTextCharacter* PS4_SYSV_ABI
sceFontCharacterRefersTextBack(OrbisFontTextCharacter* textCharacter);
OrbisFontTextCharacter* PS4_SYSV_ABI
sceFontCharacterRefersTextNext(OrbisFontTextCharacter* textCharacter);
s32 PS4_SYSV_ABI sceFontCharactersRefersTextCodes();
s32 PS4_SYSV_ABI sceFontClearDeviceCache();
s32 PS4_SYSV_ABI sceFontCloseFont();
s32 PS4_SYSV_ABI sceFontControl();
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 sceFontCreateRenderer();
s32 PS4_SYSV_ABI sceFontCreateRendererWithEdition();
s32 PS4_SYSV_ABI sceFontCreateString();
s32 PS4_SYSV_ABI sceFontCreateWords();
s32 PS4_SYSV_ABI sceFontCreateWritingLine();
s32 PS4_SYSV_ABI sceFontDefineAttribute();
s32 PS4_SYSV_ABI sceFontDeleteGlyph();
s32 PS4_SYSV_ABI sceFontDestroyGraphicsDevice();
s32 PS4_SYSV_ABI sceFontDestroyGraphicsService();
s32 PS4_SYSV_ABI sceFontDestroyLibrary();
s32 PS4_SYSV_ABI sceFontDestroyRenderer();
s32 PS4_SYSV_ABI sceFontDestroyString();
s32 PS4_SYSV_ABI sceFontDestroyWords();
s32 PS4_SYSV_ABI sceFontDestroyWritingLine();
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 sceFontGetEffectSlant();
s32 PS4_SYSV_ABI sceFontGetEffectWeight();
s32 PS4_SYSV_ABI sceFontGetFontGlyphsCount();
s32 PS4_SYSV_ABI sceFontGetFontGlyphsOutlineProfile();
s32 PS4_SYSV_ABI sceFontGetFontMetrics();
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 sceFontGetPixelResolution();
s32 PS4_SYSV_ABI sceFontGetRenderCharGlyphMetrics();
s32 PS4_SYSV_ABI sceFontGetRenderEffectSlant();
s32 PS4_SYSV_ABI sceFontGetRenderEffectWeight();
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 sceFontGetScalePoint();
s32 PS4_SYSV_ABI sceFontGetScriptLanguage();
s32 PS4_SYSV_ABI sceFontGetTypographicDesign();
s32 PS4_SYSV_ABI sceFontGetVerticalLayout();
s32 PS4_SYSV_ABI sceFontGlyphDefineAttribute();
s32 PS4_SYSV_ABI sceFontGlyphGetAttribute();
s32 PS4_SYSV_ABI sceFontGlyphGetGlyphForm();
s32 PS4_SYSV_ABI sceFontGlyphGetMetricsForm();
s32 PS4_SYSV_ABI sceFontGlyphGetScalePixel();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetrics();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontal();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontalAdvance();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontalX();
s32 PS4_SYSV_ABI sceFontGlyphRefersOutline();
s32 PS4_SYSV_ABI sceFontGlyphRenderImage();
s32 PS4_SYSV_ABI sceFontGlyphRenderImageHorizontal();
s32 PS4_SYSV_ABI sceFontGlyphRenderImageVertical();
s32 PS4_SYSV_ABI sceFontGraphicsBeginFrame();
s32 PS4_SYSV_ABI sceFontGraphicsDrawingCancel();
s32 PS4_SYSV_ABI sceFontGraphicsDrawingFinish();
s32 PS4_SYSV_ABI sceFontGraphicsEndFrame();
s32 PS4_SYSV_ABI sceFontGraphicsExchangeResource();
s32 PS4_SYSV_ABI sceFontGraphicsFillMethodInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotSetLayout();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotSetMapping();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetFillEffect();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetLayout();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetMapping();
s32 PS4_SYSV_ABI sceFontGraphicsGetDeviceUsage();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInit();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInitCircular();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInitRoundish();
s32 PS4_SYSV_ABI sceFontGraphicsRelease();
s32 PS4_SYSV_ABI sceFontGraphicsRenderResource();
s32 PS4_SYSV_ABI sceFontGraphicsSetFramePolicy();
s32 PS4_SYSV_ABI sceFontGraphicsSetupClipping();
s32 PS4_SYSV_ABI sceFontGraphicsSetupColorRates();
s32 PS4_SYSV_ABI sceFontGraphicsSetupFillMethod();
s32 PS4_SYSV_ABI sceFontGraphicsSetupFillRates();
s32 PS4_SYSV_ABI sceFontGraphicsSetupGlyphFill();
s32 PS4_SYSV_ABI sceFontGraphicsSetupGlyphFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsSetupHandleDefault();
s32 PS4_SYSV_ABI sceFontGraphicsSetupLocation();
s32 PS4_SYSV_ABI sceFontGraphicsSetupPositioning();
s32 PS4_SYSV_ABI sceFontGraphicsSetupRotation();
s32 PS4_SYSV_ABI sceFontGraphicsSetupScaling();
s32 PS4_SYSV_ABI sceFontGraphicsSetupShapeFill();
s32 PS4_SYSV_ABI sceFontGraphicsSetupShapeFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsStructureCanvas();
s32 PS4_SYSV_ABI sceFontGraphicsStructureCanvasSequence();
s32 PS4_SYSV_ABI sceFontGraphicsStructureDesign();
s32 PS4_SYSV_ABI sceFontGraphicsStructureDesignResource();
s32 PS4_SYSV_ABI sceFontGraphicsStructureSurfaceTexture();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateClipping();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateColorRates();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateFillMethod();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateFillRates();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateGlyphFill();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateGlyphFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateLocation();
s32 PS4_SYSV_ABI sceFontGraphicsUpdatePositioning();
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 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 sceFontRenderCharGlyphImageVertical();
s32 PS4_SYSV_ABI sceFontRendererGetOutlineBufferSize();
s32 PS4_SYSV_ABI sceFontRendererResetOutlineBuffer();
s32 PS4_SYSV_ABI sceFontRendererSetOutlineBufferPolicy();
void PS4_SYSV_ABI sceFontRenderSurfaceInit(OrbisFontRenderSurface* renderSurface, void* buffer,
int bufWidthByte, int pixelSizeByte, int widthPixel,
int heightPixel);
void PS4_SYSV_ABI sceFontRenderSurfaceSetScissor(OrbisFontRenderSurface* renderSurface, int x0,
int y0, int w, int h);
s32 PS4_SYSV_ABI sceFontRenderSurfaceSetStyleFrame(OrbisFontRenderSurface* renderSurface,
OrbisFontStyleFrame* styleFrame);
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 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 sceFontSetupRenderScalePoint();
s32 PS4_SYSV_ABI sceFontStringGetTerminateCode();
s32 PS4_SYSV_ABI sceFontStringGetTerminateOrder();
s32 PS4_SYSV_ABI sceFontStringGetWritingForm();
s32 PS4_SYSV_ABI sceFontStringRefersRenderCharacters();
s32 PS4_SYSV_ABI sceFontStringRefersTextCharacters();
s32 PS4_SYSV_ABI sceFontStyleFrameGetEffectSlant(OrbisFontStyleFrame* styleFrame,
float* slantRatio);
s32 PS4_SYSV_ABI sceFontStyleFrameGetEffectWeight(OrbisFontStyleFrame* fontStyleFrame,
float* weightXScale, float* weightYScale,
uint32_t* mode);
s32 PS4_SYSV_ABI sceFontStyleFrameGetResolutionDpi();
s32 PS4_SYSV_ABI sceFontStyleFrameGetScalePixel(OrbisFontStyleFrame* styleFrame, float* w,
float* h);
s32 PS4_SYSV_ABI sceFontStyleFrameGetScalePoint();
s32 PS4_SYSV_ABI sceFontStyleFrameInit();
s32 PS4_SYSV_ABI sceFontStyleFrameSetEffectSlant();
s32 PS4_SYSV_ABI sceFontStyleFrameSetEffectWeight();
s32 PS4_SYSV_ABI sceFontStyleFrameSetResolutionDpi();
s32 PS4_SYSV_ABI sceFontStyleFrameSetScalePixel();
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 sceFontSupportGlyphs();
s32 PS4_SYSV_ABI sceFontSupportSystemFonts();
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 sceFontWordsFindWordCharacters();
s32 PS4_SYSV_ABI sceFontWritingGetRenderMetrics();
s32 PS4_SYSV_ABI sceFontWritingInit();
s32 PS4_SYSV_ABI sceFontWritingLineClear();
s32 PS4_SYSV_ABI sceFontWritingLineGetOrderingSpace();
s32 PS4_SYSV_ABI sceFontWritingLineGetRenderMetrics();
s32 PS4_SYSV_ABI sceFontWritingLineRefersRenderStep();
s32 PS4_SYSV_ABI sceFontWritingLineWritesOrder();
s32 PS4_SYSV_ABI sceFontWritingRefersRenderStep();
s32 PS4_SYSV_ABI sceFontWritingRefersRenderStepCharacter();
s32 PS4_SYSV_ABI sceFontWritingSetMaskInvisible();
s32 PS4_SYSV_ABI Func_00F4D778F1C88CB3();
s32 PS4_SYSV_ABI Func_03C650025FBB0DE7();
s32 PS4_SYSV_ABI Func_07EAB8A163B27E1A();
s32 PS4_SYSV_ABI Func_09408E88E4F97CE3();
s32 PS4_SYSV_ABI Func_09F92905ED82A814();
s32 PS4_SYSV_ABI Func_0D142CEE1AB21ABE();
s32 PS4_SYSV_ABI Func_14BD2E9E119C16F2();
s32 PS4_SYSV_ABI Func_1AC53C9EDEAE8D75();
s32 PS4_SYSV_ABI Func_1D401185D5E24C3D();
s32 PS4_SYSV_ABI Func_1E83CD20C2CC996F();
s32 PS4_SYSV_ABI Func_314B1F765B9FE78A();
s32 PS4_SYSV_ABI Func_350E6725FEDE29E1();
s32 PS4_SYSV_ABI Func_3DB773F0A604BF39();
s32 PS4_SYSV_ABI Func_4FF49DD21E311B1C();
s32 PS4_SYSV_ABI Func_526287664A493981();
s32 PS4_SYSV_ABI Func_55CA718DBC84A6E9();
s32 PS4_SYSV_ABI Func_563FC5F0706A8B4D();
s32 PS4_SYSV_ABI Func_569E2ECD34290F45();
s32 PS4_SYSV_ABI Func_5A04775B6BE47685();
s32 PS4_SYSV_ABI Func_5FD93BCAB6F79750();
s32 PS4_SYSV_ABI Func_62B5398F864BD3B4();
s32 PS4_SYSV_ABI Func_6F9010294D822367();
s32 PS4_SYSV_ABI Func_7757E947423A7A67();
s32 PS4_SYSV_ABI Func_7E06BA52077F54FA();
s32 PS4_SYSV_ABI Func_93B36DEA021311D6();
s32 PS4_SYSV_ABI Func_94B0891E7111598A();
s32 PS4_SYSV_ABI Func_9785C9128C2FE7CD();
s32 PS4_SYSV_ABI Func_97DFBC9B65FBC0E1();
s32 PS4_SYSV_ABI Func_ACD9717405D7D3CA();
s32 PS4_SYSV_ABI Func_B19A8AEC3FD4F16F();
s32 PS4_SYSV_ABI Func_C10F488AD7CF103D();
s32 PS4_SYSV_ABI Func_D0C8B5FF4A6826C7();
s32 PS4_SYSV_ABI Func_E48D3CD01C342A33();
s32 PS4_SYSV_ABI Func_EAC96B2186B71E14();
s32 PS4_SYSV_ABI Func_FE4788A96EF46256();
s32 PS4_SYSV_ABI Func_FE7E5AE95D3058F5();
void RegisterlibSceFont(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Font
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <cstdint>
#include "common/types.h"
namespace Core::Loader {
class SymbolsResolver;
}
namespace Libraries::Font {
struct OrbisFontHandleOpaque {
u32 reserved[64];
};
using OrbisFontLib = void*;
using OrbisFontHandle = OrbisFontHandleOpaque*;
using OrbisFontRendererCreateParams = void*;
using OrbisFontRenderer = void*;
using OrbisFontLibCreateParams = void*;
struct OrbisFontMem;
struct OrbisFontOpenParams {
u16 tag;
u16 pad16;
u32 flags;
u32 subfont_index;
s32 unique_id;
const void* reserved_ptr2;
const void* reserved_ptr1;
};
// Fontlib APIs use Unicode scalar values (UTF-32 codepoints) in `u32` parameters such as `code` and
// `codepoint`. Codepoint-to-glyph resolution is performed via FreeType charmaps, with additional
// sysfont mapping and fallback behavior handled internally.
struct OrbisFontGlyphMetrics {
float width;
float height;
struct {
float bearingX;
float bearingY;
float advance;
} Horizontal;
struct {
float bearingX;
float bearingY;
float advance;
} Vertical;
};
struct OrbisFontGlyphMetricsHorizontal {
float width;
float height;
struct {
float bearing_x;
float bearing_y;
float advance;
} horizontal;
};
struct OrbisFontGlyphMetricsHorizontalX {
float width;
struct {
float bearing_x;
float advance;
} horizontal;
};
struct OrbisFontGlyphMetricsHorizontalAdvance {
struct {
float advance;
} horizontal;
};
struct OrbisFontKerning {
float offsetX;
float offsetY;
float positionX;
float positionY;
};
struct OrbisFontGlyphImageMetrics {
float bearingX;
float bearingY;
float advance;
float stride;
u32 width;
u32 height;
};
struct OrbisFontGenerateGlyphParams {
u16 id;
u16 res0;
// Bitmask copied into `OrbisFontGlyphOpaque::flags`. Only bits `0x01` and `0x10` are accepted
// by the public API; other bits are rejected as invalid.
u16 form_options;
u8 glyph_form;
u8 metrics_form;
const OrbisFontMem* mem;
void* res1;
void* res2;
};
struct OrbisFontGlyphOutlinePoint {
float x;
float y;
};
struct OrbisFontGlyphOutline {
s16 contours_cnt;
s16 points_cnt;
u32 outline_flags;
OrbisFontGlyphOutlinePoint* points_ptr;
u8* tags_ptr;
u16* contour_end_idx;
};
struct OrbisFontGlyphOpaque {
u16 magic;
// Encoded flags copied from `OrbisFontGenerateGlyphParams::form_options`.
u16 flags;
u8 glyph_form;
u8 metrics_form;
u16 em_size;
u16 baseline;
u16 height_px;
u16 origin_x;
u16 origin_y;
float scale_x;
float base_scale;
const OrbisFontMem* memory;
};
using OrbisFontGlyph = OrbisFontGlyphOpaque*;
struct OrbisFontResultStage {
u8* p_00;
u32 u32_08;
u32 u32_0C;
u32 u32_10;
};
struct OrbisFontSurfaceImage {
u8* address;
u32 widthByte;
u8 pixelSizeByte;
u8 pixelFormat;
u16 pad16;
};
struct OrbisFontRenderOutput {
const OrbisFontResultStage* stage;
OrbisFontSurfaceImage SurfaceImage;
struct {
u32 x;
u32 y;
u32 w;
u32 h;
} UpdateRect;
OrbisFontGlyphImageMetrics ImageMetrics;
};
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 {
struct OrbisFontTextCharacter* next;
struct OrbisFontTextCharacter* prev;
void* textOrder;
u32 characterCode;
u8 unknown_0x31;
u8 unknown_0x33;
u8 charType;
u8 bidiLevel;
u8 formatFlags;
};
struct OrbisFontRenderSurface {
void* buffer;
s32 widthByte;
s8 pixelSizeByte;
u8 pad0;
u8 styleFlag;
u8 pad2;
s32 width, height;
u32 sc_x0;
u32 sc_y0;
u32 sc_x1;
u32 sc_y1;
u64 reserved_q[11];
};
struct OrbisFontStyleFrame {
/*0x00*/ u16 magic;
// `flags1` controls which fields are considered valid overrides:
// - bit0: scale override present (scaleUnit/scalePixelW/scalePixelH)
// - bit1: slant override present (slantRatio)
// - bit2: weight override present (effectWeightX/effectWeightY)
/*0x02*/ u8 flags1;
/*0x03*/ u8 flags2;
/*0x04*/ u32 hDpi;
/*0x08*/ u32 vDpi;
// `scaleUnit` selects how scale fields are interpreted:
// - 0: pixel scale (`scalePixelW/scalePixelH`)
// - 1: point scale (converted via DPI by style-state getters)
/*0x0C*/ u32 scaleUnit;
/*0x10*/ float baseScale;
/*0x14*/ float scalePixelW;
/*0x18*/ float scalePixelH;
/*0x1C*/ float effectWeightX;
/*0x20*/ float effectWeightY;
/*0x24*/ float slantRatio;
/*0x28*/ u32 reserved_0x28;
/*0x2C*/ u32 layout_cache_state;
// Packed cache metadata:
// - bits [7:0] cache flags
// - bits [31:16] direction word
/*0x30*/ u32 cache_flags_and_direction;
/*0x34*/ u32 cache_lock_word;
/*0x38*/ u8 layout_cache_bytes[0x20];
/*0x58*/ u32 reserved_0x58;
/*0x5C*/ u32 cached_scalar_bits;
};
static_assert(sizeof(OrbisFontStyleFrame) == 0x60, "OrbisFontStyleFrame size");
static_assert(offsetof(OrbisFontStyleFrame, magic) == 0x00, "OrbisFontStyleFrame magic offset");
static_assert(offsetof(OrbisFontStyleFrame, flags1) == 0x02, "OrbisFontStyleFrame flags1 offset");
static_assert(offsetof(OrbisFontStyleFrame, hDpi) == 0x04, "OrbisFontStyleFrame hDpi offset");
static_assert(offsetof(OrbisFontStyleFrame, vDpi) == 0x08, "OrbisFontStyleFrame vDpi offset");
static_assert(offsetof(OrbisFontStyleFrame, scaleUnit) == 0x0C,
"OrbisFontStyleFrame scaleUnit offset");
static_assert(offsetof(OrbisFontStyleFrame, scalePixelW) == 0x14,
"OrbisFontStyleFrame scalePixelW offset");
static_assert(offsetof(OrbisFontStyleFrame, scalePixelH) == 0x18,
"OrbisFontStyleFrame scalePixelH offset");
static_assert(offsetof(OrbisFontStyleFrame, cache_lock_word) == 0x34,
"OrbisFontStyleFrame cache_lock_word offset");
static_assert(offsetof(OrbisFontStyleFrame, reserved_0x58) == 0x58,
"OrbisFontStyleFrame reserved_0x58 offset");
static_assert(sizeof(OrbisFontGlyphMetrics) == 0x20, "OrbisFontGlyphMetrics size");
static_assert(sizeof(OrbisFontResultStage) == 0x18, "OrbisFontTransImage size");
static_assert(sizeof(OrbisFontSurfaceImage) == 0x10, "OrbisFontSurfaceImage size");
static_assert(sizeof(OrbisFontRenderOutput) == 0x40, "OrbisFontRenderOutput size");
struct OrbisFontHorizontalLayout {
float baselineOffset;
float lineAdvance;
float decorationExtent;
};
struct OrbisFontVerticalLayout {
float baselineOffsetX;
float columnAdvance;
float decorationSpan;
};
#if INTPTR_MAX == INT64_MAX
static_assert(sizeof(OrbisFontOpenParams) == 32, "OrbisFontOpenParams size");
static_assert(sizeof(OrbisFontGlyphMetrics) == 32, "OrbisFontGlyphMetrics size");
static_assert(sizeof(OrbisFontKerning) == 16, "OrbisFontKerning size");
static_assert(sizeof(OrbisFontRenderSurface) == 128, "OrbisFontRenderSurface ABI size");
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();
s32 PS4_SYSV_ABI sceFontCharacterGetTextFontCode();
s32 PS4_SYSV_ABI sceFontCharacterGetTextOrder(OrbisFontTextCharacter* textCharacter,
void** pTextOrder);
u32 PS4_SYSV_ABI sceFontCharacterLooksFormatCharacters(OrbisFontTextCharacter* textCharacter);
u32 PS4_SYSV_ABI sceFontCharacterLooksWhiteSpace(OrbisFontTextCharacter* textCharacter);
OrbisFontTextCharacter* PS4_SYSV_ABI
sceFontCharacterRefersTextBack(OrbisFontTextCharacter* textCharacter);
OrbisFontTextCharacter* PS4_SYSV_ABI
sceFontCharacterRefersTextNext(OrbisFontTextCharacter* textCharacter);
s32 PS4_SYSV_ABI sceFontCharactersRefersTextCodes();
s32 PS4_SYSV_ABI sceFontClearDeviceCache(OrbisFontLib library);
s32 PS4_SYSV_ABI sceFontCloseFont();
s32 PS4_SYSV_ABI sceFontControl();
s32 PS4_SYSV_ABI sceFontCreateGraphicsDevice();
s32 PS4_SYSV_ABI sceFontCreateGraphicsService();
s32 PS4_SYSV_ABI sceFontCreateGraphicsServiceWithEdition();
s32 PS4_SYSV_ABI sceFontCreateLibrary(const OrbisFontMem* memory,
OrbisFontLibCreateParams create_params,
OrbisFontLib* pLibrary);
s32 PS4_SYSV_ABI sceFontCreateLibraryWithEdition(const OrbisFontMem* memory,
OrbisFontLibCreateParams create_params,
u64 edition, OrbisFontLib* pLibrary);
s32 PS4_SYSV_ABI sceFontCreateRenderer(const OrbisFontMem* memory,
OrbisFontRendererCreateParams create_params,
OrbisFontRenderer* pRenderer);
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();
s32 PS4_SYSV_ABI sceFontDefineAttribute();
s32 PS4_SYSV_ABI sceFontDeleteGlyph(const OrbisFontMem* memory, OrbisFontGlyph* glyph);
s32 PS4_SYSV_ABI sceFontDestroyGraphicsDevice();
s32 PS4_SYSV_ABI sceFontDestroyGraphicsService();
s32 PS4_SYSV_ABI sceFontDestroyLibrary(OrbisFontLib* pLibrary);
s32 PS4_SYSV_ABI sceFontDestroyRenderer(OrbisFontRenderer* pRenderer);
s32 PS4_SYSV_ABI sceFontDestroyString();
s32 PS4_SYSV_ABI sceFontDestroyWords();
s32 PS4_SYSV_ABI sceFontDestroyWritingLine();
s32 PS4_SYSV_ABI sceFontDettachDeviceCacheBuffer();
s32 PS4_SYSV_ABI sceFontGenerateCharGlyph(OrbisFontHandle glyph_handle, u32 codepoint,
const OrbisFontGenerateGlyphParams* gen_params,
OrbisFontGlyph* glyph_out);
s32 PS4_SYSV_ABI sceFontGetAttribute();
s32 PS4_SYSV_ABI sceFontGetCharGlyphCode();
s32 PS4_SYSV_ABI sceFontGetCharGlyphMetrics(OrbisFontHandle fontHandle, u32 code,
OrbisFontGlyphMetrics* metrics);
s32 PS4_SYSV_ABI sceFontGetEffectSlant(OrbisFontHandle fontHandle, float* slantRatio);
s32 PS4_SYSV_ABI sceFontGetEffectWeight(OrbisFontHandle fontHandle, float* weightXScale,
float* weightYScale, u32* mode);
s32 PS4_SYSV_ABI sceFontGetFontGlyphsCount();
s32 PS4_SYSV_ABI sceFontGetFontGlyphsOutlineProfile();
s32 PS4_SYSV_ABI sceFontGetFontMetrics();
s32 PS4_SYSV_ABI sceFontGetFontResolution();
s32 PS4_SYSV_ABI sceFontGetFontStyleInformation();
s32 PS4_SYSV_ABI sceFontGetGlyphExpandBufferState();
s32 PS4_SYSV_ABI sceFontGetHorizontalLayout(OrbisFontHandle fontHandle,
OrbisFontHorizontalLayout* layout);
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(OrbisFontHandle fontHandle, u32 codepoint,
OrbisFontGlyphMetrics* out_metrics);
s32 PS4_SYSV_ABI sceFontGetRenderEffectSlant(OrbisFontHandle fontHandle, float* slantRatio);
s32 PS4_SYSV_ABI sceFontGetRenderEffectWeight(OrbisFontHandle fontHandle, float* weightXScale,
float* weightYScale, u32* mode);
s32 PS4_SYSV_ABI sceFontGetRenderScaledKerning();
s32 PS4_SYSV_ABI sceFontGetRenderScalePixel(OrbisFontHandle fontHandle, float* out_w, float* out_h);
s32 PS4_SYSV_ABI sceFontGetRenderScalePoint(OrbisFontHandle fontHandle, float* out_w, float* out_h);
s32 PS4_SYSV_ABI sceFontGetResolutionDpi();
s32 PS4_SYSV_ABI sceFontGetScalePixel(OrbisFontHandle fontHandle, float* out_w, float* out_h);
s32 PS4_SYSV_ABI sceFontGetScalePoint(OrbisFontHandle fontHandle, float* out_w, float* out_h);
s32 PS4_SYSV_ABI sceFontGetScriptLanguage();
s32 PS4_SYSV_ABI sceFontGetTypographicDesign();
s32 PS4_SYSV_ABI sceFontGetVerticalLayout(OrbisFontHandle fontHandle,
OrbisFontVerticalLayout* layout);
s32 PS4_SYSV_ABI sceFontGlyphDefineAttribute();
s32 PS4_SYSV_ABI sceFontGlyphGetAttribute();
s32 PS4_SYSV_ABI sceFontGlyphGetGlyphForm();
s32 PS4_SYSV_ABI sceFontGlyphGetMetricsForm();
s32 PS4_SYSV_ABI sceFontGlyphGetScalePixel();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetrics();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontal();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontalAdvance();
s32 PS4_SYSV_ABI sceFontGlyphRefersMetricsHorizontalX();
OrbisFontGlyphOutline* PS4_SYSV_ABI sceFontGlyphRefersOutline(OrbisFontGlyph glyph);
s32 PS4_SYSV_ABI sceFontGlyphRenderImage();
s32 PS4_SYSV_ABI sceFontGlyphRenderImageHorizontal();
s32 PS4_SYSV_ABI sceFontGlyphRenderImageVertical();
s32 PS4_SYSV_ABI sceFontGraphicsBeginFrame();
s32 PS4_SYSV_ABI sceFontGraphicsDrawingCancel();
s32 PS4_SYSV_ABI sceFontGraphicsDrawingFinish();
s32 PS4_SYSV_ABI sceFontGraphicsEndFrame();
s32 PS4_SYSV_ABI sceFontGraphicsExchangeResource();
s32 PS4_SYSV_ABI sceFontGraphicsFillMethodInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotSetLayout();
s32 PS4_SYSV_ABI sceFontGraphicsFillPlotSetMapping();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesInit();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetFillEffect();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetLayout();
s32 PS4_SYSV_ABI sceFontGraphicsFillRatesSetMapping();
s32 PS4_SYSV_ABI sceFontGraphicsGetDeviceUsage();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInit();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInitCircular();
s32 PS4_SYSV_ABI sceFontGraphicsRegionInitRoundish();
s32 PS4_SYSV_ABI sceFontGraphicsRelease();
s32 PS4_SYSV_ABI sceFontGraphicsRenderResource();
s32 PS4_SYSV_ABI sceFontGraphicsSetFramePolicy();
s32 PS4_SYSV_ABI sceFontGraphicsSetupClipping();
s32 PS4_SYSV_ABI sceFontGraphicsSetupColorRates();
s32 PS4_SYSV_ABI sceFontGraphicsSetupFillMethod();
s32 PS4_SYSV_ABI sceFontGraphicsSetupFillRates();
s32 PS4_SYSV_ABI sceFontGraphicsSetupGlyphFill();
s32 PS4_SYSV_ABI sceFontGraphicsSetupGlyphFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsSetupHandleDefault();
s32 PS4_SYSV_ABI sceFontGraphicsSetupLocation();
s32 PS4_SYSV_ABI sceFontGraphicsSetupPositioning();
s32 PS4_SYSV_ABI sceFontGraphicsSetupRotation();
s32 PS4_SYSV_ABI sceFontGraphicsSetupScaling();
s32 PS4_SYSV_ABI sceFontGraphicsSetupShapeFill();
s32 PS4_SYSV_ABI sceFontGraphicsSetupShapeFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsStructureCanvas();
s32 PS4_SYSV_ABI sceFontGraphicsStructureCanvasSequence();
s32 PS4_SYSV_ABI sceFontGraphicsStructureDesign();
s32 PS4_SYSV_ABI sceFontGraphicsStructureDesignResource();
s32 PS4_SYSV_ABI sceFontGraphicsStructureSurfaceTexture();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateClipping();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateColorRates();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateFillMethod();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateFillRates();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateGlyphFill();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateGlyphFillPlot();
s32 PS4_SYSV_ABI sceFontGraphicsUpdateLocation();
s32 PS4_SYSV_ABI sceFontGraphicsUpdatePositioning();
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(OrbisFontMem* mem_desc, void* region_addr, u32 region_size,
const OrbisFontMemInterface* iface, void* mspace_obj,
OrbisFontMemDestroyCb destroy_cb, void* destroy_ctx);
s32 PS4_SYSV_ABI sceFontMemoryTerm(OrbisFontMem* mem_desc);
s32 PS4_SYSV_ABI sceFontOpenFontFile(OrbisFontLib library, const char* guest_path, u32 open_mode,
const OrbisFontOpenParams* open_detail,
OrbisFontHandle* out_handle);
s32 PS4_SYSV_ABI sceFontOpenFontInstance(OrbisFontHandle fontHandle, OrbisFontHandle templateFont,
OrbisFontHandle* pFontHandle);
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(OrbisFontHandle fontHandle, u32 code,
OrbisFontRenderSurface* surf, float x, float y,
OrbisFontGlyphMetrics* metrics,
OrbisFontRenderOutput* result);
s32 PS4_SYSV_ABI sceFontRendererGetOutlineBufferSize(OrbisFontRenderer fontRenderer, u32* size);
s32 PS4_SYSV_ABI sceFontRendererResetOutlineBuffer(OrbisFontRenderer fontRenderer);
s32 PS4_SYSV_ABI sceFontRendererSetOutlineBufferPolicy(OrbisFontRenderer fontRenderer,
u64 bufferPolicy, u32 basalSize,
u32 limitSize);
void PS4_SYSV_ABI sceFontRenderSurfaceInit(OrbisFontRenderSurface* renderSurface, void* buffer,
int bufWidthByte, int pixelSizeByte, int widthPixel,
int heightPixel);
void PS4_SYSV_ABI sceFontRenderSurfaceSetScissor(OrbisFontRenderSurface* renderSurface, int x0,
int y0, int w, int h);
s32 PS4_SYSV_ABI sceFontRenderSurfaceSetStyleFrame(OrbisFontRenderSurface* renderSurface,
OrbisFontStyleFrame* styleFrame);
s32 PS4_SYSV_ABI sceFontSetEffectSlant(OrbisFontHandle fontHandle, float slantRatio);
s32 PS4_SYSV_ABI sceFontSetEffectWeight(OrbisFontHandle fontHandle, float weightXScale,
float weightYScale, u32 mode);
s32 PS4_SYSV_ABI sceFontSetFontsOpenMode();
s32 PS4_SYSV_ABI sceFontSetResolutionDpi(OrbisFontHandle fontHandle, u32 h_dpi, u32 v_dpi);
s32 PS4_SYSV_ABI sceFontSetScalePixel(OrbisFontHandle fontHandle, float w, float h);
s32 PS4_SYSV_ABI sceFontSetScalePoint(OrbisFontHandle fontHandle, float w, float h);
s32 PS4_SYSV_ABI sceFontSetScriptLanguage();
s32 PS4_SYSV_ABI sceFontSetTypographicDesign();
s32 PS4_SYSV_ABI sceFontSetupRenderEffectSlant(OrbisFontHandle fontHandle, float slantRatio);
s32 PS4_SYSV_ABI sceFontSetupRenderEffectWeight(OrbisFontHandle fontHandle, float weightXScale,
float weightYScale, u32 mode);
s32 PS4_SYSV_ABI sceFontSetupRenderScalePixel(OrbisFontHandle fontHandle, float w, float h);
s32 PS4_SYSV_ABI sceFontSetupRenderScalePoint(OrbisFontHandle fontHandle, float w, float h);
s32 PS4_SYSV_ABI sceFontStringGetTerminateCode();
s32 PS4_SYSV_ABI sceFontStringGetTerminateOrder();
s32 PS4_SYSV_ABI sceFontStringGetWritingForm();
s32 PS4_SYSV_ABI sceFontStringRefersRenderCharacters();
s32 PS4_SYSV_ABI sceFontStringRefersTextCharacters();
s32 PS4_SYSV_ABI sceFontStyleFrameGetEffectSlant(OrbisFontStyleFrame* styleFrame,
float* slantRatio);
s32 PS4_SYSV_ABI sceFontStyleFrameGetEffectWeight(OrbisFontStyleFrame* fontStyleFrame,
float* weightXScale, float* weightYScale,
uint32_t* mode);
s32 PS4_SYSV_ABI sceFontStyleFrameGetResolutionDpi(const OrbisFontStyleFrame* styleFrame,
u32* h_dpi, u32* v_dpi);
s32 PS4_SYSV_ABI sceFontStyleFrameGetScalePixel(const OrbisFontStyleFrame* styleFrame, float* w,
float* h);
s32 PS4_SYSV_ABI sceFontStyleFrameGetScalePoint(const OrbisFontStyleFrame* styleFrame, float* w,
float* h);
s32 PS4_SYSV_ABI sceFontStyleFrameInit(OrbisFontStyleFrame* styleFrame);
s32 PS4_SYSV_ABI sceFontStyleFrameSetEffectSlant(OrbisFontStyleFrame* styleFrame, float slantRatio);
s32 PS4_SYSV_ABI sceFontStyleFrameSetEffectWeight(OrbisFontStyleFrame* styleFrame,
float weightXScale, float weightYScale, u32 mode);
s32 PS4_SYSV_ABI sceFontStyleFrameSetResolutionDpi(OrbisFontStyleFrame* styleFrame, u32 h_dpi,
u32 v_dpi);
s32 PS4_SYSV_ABI sceFontStyleFrameSetScalePixel(OrbisFontStyleFrame* styleFrame, float w, float h);
s32 PS4_SYSV_ABI sceFontStyleFrameSetScalePoint(OrbisFontStyleFrame* styleFrame, float w, float h);
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetEffectSlant(OrbisFontStyleFrame* styleFrame);
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetEffectWeight(OrbisFontStyleFrame* styleFrame);
s32 PS4_SYSV_ABI sceFontStyleFrameUnsetScale(OrbisFontStyleFrame* styleFrame);
s32 PS4_SYSV_ABI sceFontSupportExternalFonts(OrbisFontLib library, u32 fontMax, u32 formats);
s32 PS4_SYSV_ABI sceFontSupportGlyphs();
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(OrbisFontHandle fontHandle);
s32 PS4_SYSV_ABI sceFontWordsFindWordCharacters();
s32 PS4_SYSV_ABI sceFontWritingGetRenderMetrics();
s32 PS4_SYSV_ABI sceFontWritingInit();
s32 PS4_SYSV_ABI sceFontWritingLineClear();
s32 PS4_SYSV_ABI sceFontWritingLineGetOrderingSpace();
s32 PS4_SYSV_ABI sceFontWritingLineGetRenderMetrics();
s32 PS4_SYSV_ABI sceFontWritingLineRefersRenderStep();
s32 PS4_SYSV_ABI sceFontWritingLineWritesOrder();
s32 PS4_SYSV_ABI sceFontWritingRefersRenderStep();
s32 PS4_SYSV_ABI sceFontWritingRefersRenderStepCharacter();
s32 PS4_SYSV_ABI sceFontWritingSetMaskInvisible();
s32 PS4_SYSV_ABI Func_00F4D778F1C88CB3();
s32 PS4_SYSV_ABI Func_03C650025FBB0DE7();
s32 PS4_SYSV_ABI Func_07EAB8A163B27E1A();
s32 PS4_SYSV_ABI Func_09408E88E4F97CE3();
s32 PS4_SYSV_ABI Func_09F92905ED82A814();
s32 PS4_SYSV_ABI Func_0D142CEE1AB21ABE();
s32 PS4_SYSV_ABI Func_14BD2E9E119C16F2();
s32 PS4_SYSV_ABI Func_1AC53C9EDEAE8D75();
s32 PS4_SYSV_ABI Func_1D401185D5E24C3D();
s32 PS4_SYSV_ABI Func_1E83CD20C2CC996F();
s32 PS4_SYSV_ABI Func_314B1F765B9FE78A();
s32 PS4_SYSV_ABI Func_350E6725FEDE29E1();
s32 PS4_SYSV_ABI Func_3DB773F0A604BF39();
s32 PS4_SYSV_ABI Func_4FF49DD21E311B1C();
s32 PS4_SYSV_ABI Func_526287664A493981();
s32 PS4_SYSV_ABI Func_55CA718DBC84A6E9();
s32 PS4_SYSV_ABI Func_563FC5F0706A8B4D();
s32 PS4_SYSV_ABI Func_569E2ECD34290F45();
s32 PS4_SYSV_ABI Func_5A04775B6BE47685();
s32 PS4_SYSV_ABI Func_5FD93BCAB6F79750();
s32 PS4_SYSV_ABI Func_62B5398F864BD3B4();
s32 PS4_SYSV_ABI Func_6F9010294D822367();
s32 PS4_SYSV_ABI Func_7757E947423A7A67();
s32 PS4_SYSV_ABI Func_7E06BA52077F54FA();
s32 PS4_SYSV_ABI Func_93B36DEA021311D6();
s32 PS4_SYSV_ABI Func_94B0891E7111598A();
s32 PS4_SYSV_ABI Func_9785C9128C2FE7CD();
s32 PS4_SYSV_ABI Func_97DFBC9B65FBC0E1();
s32 PS4_SYSV_ABI Func_ACD9717405D7D3CA();
s32 PS4_SYSV_ABI Func_B19A8AEC3FD4F16F();
s32 PS4_SYSV_ABI Func_C10F488AD7CF103D();
s32 PS4_SYSV_ABI Func_D0C8B5FF4A6826C7();
s32 PS4_SYSV_ABI Func_E48D3CD01C342A33();
s32 PS4_SYSV_ABI Func_EAC96B2186B71E14();
s32 PS4_SYSV_ABI Func_FE4788A96EF46256();
s32 PS4_SYSV_ABI Func_FE7E5AE95D3058F5();
void RegisterlibSceFont(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::Font

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,892 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <initializer_list>
#include <iterator>
#include <limits>
#include <memory>
#include <mutex>
#include <new>
#include <optional>
#include <string>
#include <string_view>
#include <system_error>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include <fmt/format.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include "common/config.h"
#include "common/logging/log.h"
#include "common/singleton.h"
#include "core/file_sys/fs.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/font/font.h"
#include "core/libraries/libs.h"
#include "font_error.h"
namespace Libraries::Font {
struct FontHandleOpaqueNative;
}
namespace Libraries::Font::Internal {
struct FontLibOpaque;
struct OrbisFontRenderer_;
struct FontSetCache;
template <typename T>
std::string DescribeValue(const T& value) {
using Clean = std::remove_cvref_t<T>;
if constexpr (std::is_same_v<Clean, bool>) {
return value ? "true" : "false";
} else if constexpr (std::is_pointer_v<Clean>) {
return fmt::format("{}", reinterpret_cast<const void*>(value));
} else if constexpr (std::is_floating_point_v<Clean>) {
return fmt::format("{:.6g}", value);
} else if constexpr (std::is_enum_v<Clean>) {
using Underlying = std::underlying_type_t<Clean>;
return DescribeValue(static_cast<Underlying>(value));
} else if constexpr (std::is_same_v<Clean, std::string> ||
std::is_same_v<Clean, std::string_view>) {
return fmt::format("\"{}\"", value);
} else {
return fmt::format("{}", value);
}
}
struct NamedParam {
std::string_view name;
std::string value;
};
template <typename T>
NamedParam Param(std::string_view name, const T& value) {
return NamedParam{name, DescribeValue(value)};
}
std::string FormatNamedParams(std::initializer_list<NamedParam> params);
struct ParamRecord {
std::string name;
std::string initial;
std::string current;
};
template <typename T>
struct ChangeTracked {
T before;
T after;
};
template <typename T>
struct is_change_tracked : std::false_type {};
template <typename T>
struct is_change_tracked<ChangeTracked<T>> : std::true_type {
using value_type = T;
};
template <typename T>
ChangeTracked<T> trackChange(T before, T after) {
return ChangeTracked<T>{before, after};
}
inline std::string TrimName(std::string_view name) {
const auto start = name.find_first_not_of(" \t\n\r");
if (start == std::string_view::npos) {
return {};
}
const auto end = name.find_last_not_of(" \t\n\r");
return std::string{name.substr(start, end - start + 1)};
}
inline std::vector<std::string> SplitArgumentNames(std::string_view names) {
std::vector<std::string> result;
std::string current;
int depth = 0;
for (char c : names) {
if (c == ',' && depth == 0) {
result.push_back(TrimName(current));
current.clear();
continue;
}
if (c == '(' || c == '{' || c == '[') {
++depth;
} else if (c == ')' || c == '}' || c == ']') {
depth = std::max(0, depth - 1);
}
current.push_back(c);
}
if (!current.empty() ||
(!names.empty() && names.find_first_not_of(" \t\n\r") != std::string_view::npos)) {
result.push_back(TrimName(current));
}
return result;
}
template <typename T>
ParamRecord MakeParamRecord(std::string name, T&& value) {
using Clean = std::remove_cvref_t<T>;
if constexpr (is_change_tracked<Clean>::value) {
using ValueType = typename Clean::value_type;
return ParamRecord{std::move(name), DescribeValue(value.before),
DescribeValue(value.after)};
} else {
const std::string rendered = DescribeValue(value);
return ParamRecord{std::move(name), rendered, rendered};
}
}
inline std::string FormatParamRecords(const std::vector<ParamRecord>& records) {
fmt::memory_buffer buffer;
fmt::format_to(std::back_inserter(buffer), "params:\n");
for (const auto& entry : records) {
const bool changed = entry.initial != entry.current;
if (changed) {
fmt::format_to(std::back_inserter(buffer), "{}: {} -> {}\n", entry.name, entry.initial,
entry.current);
} else {
fmt::format_to(std::back_inserter(buffer), "{}: {}\n", entry.name, entry.initial);
}
}
return fmt::to_string(buffer);
}
template <typename... Args>
std::string formatParamsImpl(const char* arg_names, Args&&... args) {
std::vector<std::string> names = SplitArgumentNames(arg_names ? arg_names : "");
std::vector<ParamRecord> records;
records.reserve(sizeof...(Args));
std::size_t index = 0;
auto append_record = [&](auto&& value) {
std::string name = (index < names.size() && !names[index].empty())
? std::move(names[index])
: fmt::format("arg{}", index);
++index;
records.push_back(MakeParamRecord(std::move(name), std::forward<decltype(value)>(value)));
};
(append_record(std::forward<Args>(args)), ...);
return FormatParamRecords(records);
}
inline void log_info(std::string_view message) {
LOG_INFO(Lib_Font, "{}", message);
}
inline void log_debug(std::string_view message) {
LOG_DEBUG(Lib_Font, "{}", message);
}
#define formatParams(...) formatParamsImpl(#__VA_ARGS__ __VA_OPT__(, ) __VA_ARGS__)
struct FontSetSelector;
struct GlyphEntry {
std::vector<std::uint8_t> bitmap;
int w = 0;
int h = 0;
int x0 = 0;
int y0 = 0;
int x1 = 0;
int y1 = 0;
float advance = 0.0f;
float bearingX = 0.0f;
};
struct FontState {
// `scale_*` fields are controlled by style-state setters and are interpreted according to the
// style frame `scaleUnit` (pixel vs point). Public APIs accept codepoints as UTF-32 scalar
// values; glyph lookup and rendering uses FreeType + deterministic fallback selection.
//
// Fallback behavior (high level):
// - A font handle may have an external face (opened from file/memory) and, optionally, a
// sysfont selection (font_set_type + primary sysfont + additional fallback sysfonts).
// - When a glyph is missing from the primary face, the implementation may consult the external
// face and then the configured system fallback faces to preserve observable behavior.
float scale_w = 16.0f;
float scale_h = 16.0f;
float scale_point_w = 12.0f;
float scale_point_h = 12.0f;
bool scale_point_active = false;
float render_scale_w = 16.0f;
float render_scale_h = 16.0f;
float render_scale_point_w = 12.0f;
float render_scale_point_h = 12.0f;
bool render_scale_point_active = false;
u32 dpi_x = 72;
u32 dpi_y = 72;
u32 font_set_type = 0;
std::filesystem::path system_font_path;
u32 system_font_id = 0;
float system_font_scale_factor = 1.0f;
s32 system_font_shift_value = 0;
struct SystemFallbackFace {
u32 font_id = 0;
float scale_factor = 1.0f;
s32 shift_value = 0;
std::filesystem::path path;
std::shared_ptr<std::vector<unsigned char>> bytes;
FT_Face ft_face = nullptr;
bool ready = false;
};
std::vector<SystemFallbackFace> system_fallback_faces;
Libraries::Font::OrbisFontLib library = nullptr;
bool ext_face_ready = false;
std::vector<unsigned char> ext_face_data;
FT_Face ext_ft_face = nullptr;
float ext_scale_for_height = 0.0f;
int ext_ascent = 0, ext_descent = 0, ext_lineGap = 0;
int ext_units_per_em = 0;
int ext_typo_ascent = 0, ext_typo_descent = 0, ext_typo_lineGap = 0;
bool ext_use_typo_metrics = false;
std::unordered_map<std::uint64_t, GlyphEntry> ext_cache;
std::vector<std::uint8_t> scratch;
bool logged_ext_use = false;
float cached_baseline_y = 0.0f;
bool layout_cached = false;
Libraries::Font::OrbisFontRenderer bound_renderer = nullptr;
bool system_requested = false;
std::shared_ptr<std::vector<u8>> fontset_record_storage;
std::shared_ptr<FontSetSelector> fontset_selector;
float effect_weight_x = 1.0f;
float effect_weight_y = 1.0f;
u32 effect_weight_mode = 0;
float effect_slant = 0.0f;
float render_effect_weight_x = 1.0f;
float render_effect_weight_y = 1.0f;
u32 render_effect_weight_mode = 0;
float render_effect_slant = 0.0f;
~FontState();
};
using FontAllocFn = void*(PS4_SYSV_ABI*)(void* object, u32 size);
using FontFreeFn = void(PS4_SYSV_ABI*)(void* object, void* p);
struct FtExternalFaceObj {
u32 refcount;
u32 reserved04;
u32 reserved08;
u32 sub_font_index;
u64 reserved10;
FtExternalFaceObj* next;
u64 reserved20;
u64 reserved28;
FT_Face face;
const u8* font_data;
u32 font_size;
u32 sfnt_base;
};
static_assert(offsetof(FtExternalFaceObj, sub_font_index) == 0x0C);
static_assert(offsetof(FtExternalFaceObj, next) == 0x18);
static_assert(offsetof(FtExternalFaceObj, face) == 0x30);
struct LibraryState {
bool support_system = false;
bool support_external = false;
u32 external_formats = 0;
u32 external_fontMax = 0;
const Libraries::Font::OrbisFontMem* backing_memory = nullptr;
Libraries::Font::OrbisFontLibCreateParams create_params = nullptr;
u64 edition = 0;
void* alloc_ctx = nullptr;
FontAllocFn alloc_fn = nullptr;
FontFreeFn free_fn = nullptr;
void* owned_mspace = nullptr;
u32 owned_mspace_size = 0;
void* owned_sysfonts_ctx = nullptr;
u32 owned_sysfonts_ctx_size = 0;
void* owned_external_fonts_ctx = nullptr;
u32 owned_external_fonts_ctx_size = 0;
FontLibOpaque* native = nullptr;
void* owned_device_cache = nullptr;
u32 owned_device_cache_size = 0;
};
struct FaceMetrics {
int units_per_em = 0;
int hhea_ascent = 0;
int hhea_descent = 0;
int hhea_lineGap = 0;
int typo_ascent = 0;
int typo_descent = 0;
int typo_lineGap = 0;
bool has_typo = false;
bool use_typo = false;
};
struct GeneratedGlyph {
OrbisFontGlyphOpaque glyph{};
OrbisFontGlyphMetrics metrics{};
OrbisFontGlyphMetricsHorizontal metrics_horizontal{};
OrbisFontGlyphMetricsHorizontalX metrics_horizontal_x{};
OrbisFontGlyphMetricsHorizontalAdvance metrics_horizontal_adv{};
float origin_x = 0.0f;
float origin_y = 0.0f;
float scale_x_used = 0.0f;
float scale_y_used = 0.0f;
int bbox_x0 = 0;
int bbox_y0 = 0;
int bbox_w = 0;
int bbox_h = 0;
u32 codepoint = 0;
Libraries::Font::OrbisFontHandle owner_handle{};
OrbisFontGlyphOutline outline{};
std::vector<OrbisFontGlyphOutlinePoint> outline_points;
std::vector<u8> outline_tags;
std::vector<u16> outline_contours;
bool metrics_initialized = false;
bool outline_initialized = false;
};
struct SysDriver {
using PixelResFn = u32(PS4_SYSV_ABI*)();
using InitFn = s32(PS4_SYSV_ABI*)(const void* memory, void* library);
using TermFn = s32(PS4_SYSV_ABI*)(void* library);
using SupportFn = s32(PS4_SYSV_ABI*)(void* library, u32 formats);
using OpenFn = s32(PS4_SYSV_ABI*)(void* library, u32 mode, const void* fontAddress,
u32 fontSize, u32 subFontIndex, u32 uniqueWord,
void** inoutFontObj);
using CloseFn = s32(PS4_SYSV_ABI*)(void* fontObj, u32 flags);
using ScaleFn = s32(PS4_SYSV_ABI*)(void* fontObj, u16* outUnitsPerEm, float* outScale);
using MetricFn = s32(PS4_SYSV_ABI*)(void* fontObj, u32 metricId, u16* outMetric);
using GlyphsCountFn = s32(PS4_SYSV_ABI*)(void* fontObj, u32* out_count);
using GlyphIndexFn = s32(PS4_SYSV_ABI*)(void* fontObj, u32 codepoint_u16, u32* out_glyph_index);
using SetCharWithDpiFn = s32(PS4_SYSV_ABI*)(void* fontObj, u32 dpi_x, u32 dpi_y, float scale_x,
float scale_y, float* out_scale_x,
float* out_scale_y);
using SetCharDefaultDpiFn = s32(PS4_SYSV_ABI*)(void* fontObj, float scale_x, float scale_y,
float* out_scale_x, float* out_scale_y);
using ComputeLayoutFn = s32(PS4_SYSV_ABI*)(void* fontObj, const void* style_state_block,
u8 (*out_words)[16]);
using ComputeLayoutAltFn = s32(PS4_SYSV_ABI*)(void* fontObj, const void* style_state_block,
u8 (*out_words)[16]);
using LoadGlyphCachedFn = s32(PS4_SYSV_ABI*)(void* fontObj, u32 glyphIndex, s32 mode,
std::uint64_t* out_words);
using GetGlyphMetricsFn = s32(PS4_SYSV_ABI*)(
void* fontObj, std::uint32_t* opt_param2, std::uint8_t mode, std::uint8_t* out_params,
Libraries::Font::OrbisFontGlyphMetrics* out_metrics);
using ApplyGlyphAdjustFn = s32(PS4_SYSV_ABI*)(void* fontObj, u32 p2, u32 glyphIndex, s32 p4,
s32 p5, u32* inoutGlyphIndex);
using ConfigureGlyphFn = s32(PS4_SYSV_ABI*)(void* fontObj, std::uint32_t* in_params, s32 mode,
std::uint32_t* inout_state);
/*0x00*/ u8 reserved_00[0x10];
/*0x10*/ PixelResFn pixel_resolution;
/*0x18*/ InitFn init;
/*0x20*/ TermFn term;
/*0x28*/ SupportFn support_formats;
/*0x30*/ u8 reserved_30[0x08];
/*0x38*/ OpenFn open;
/*0x40*/ CloseFn close;
/*0x48*/ u8 reserved_48[0x08];
/*0x50*/ ScaleFn scale;
/*0x58*/ u8 reserved_58[0x08];
/*0x60*/ MetricFn metric;
/*0x68*/ GlyphsCountFn glyphs_count;
/*0x70*/ u8 reserved_70[0x08];
/*0x78*/ GlyphIndexFn glyph_index;
/*0x80*/ SetCharWithDpiFn set_char_with_dpi;
/*0x88*/ SetCharDefaultDpiFn set_char_default_dpi;
/*0x90*/ u8 reserved_90[0x10];
/*0xA0*/ ComputeLayoutFn compute_layout;
/*0xA8*/ LoadGlyphCachedFn load_glyph_cached;
/*0xB0*/ u8 reserved_B0[0x08];
/*0xB8*/ GetGlyphMetricsFn get_glyph_metrics;
/*0xC0*/ u8 reserved_C0[0x20];
/*0xE0*/ ApplyGlyphAdjustFn apply_glyph_adjust;
/*0xE8*/ u8 reserved_E8[0x20];
/*0x108*/ ConfigureGlyphFn configure_glyph;
/*0x110*/ u8 reserved_0x110_pad[0x08];
/*0x118*/ ComputeLayoutAltFn compute_layout_alt;
};
static_assert(sizeof(SysDriver) == 0x120, "SysDriver size");
static_assert(offsetof(SysDriver, pixel_resolution) == 0x10, "SysDriver pixel_resolution offset");
static_assert(offsetof(SysDriver, init) == 0x18, "SysDriver init offset");
static_assert(offsetof(SysDriver, term) == 0x20, "SysDriver term offset");
static_assert(offsetof(SysDriver, support_formats) == 0x28, "SysDriver support_formats offset");
static_assert(offsetof(SysDriver, open) == 0x38, "SysDriver open offset");
static_assert(offsetof(SysDriver, close) == 0x40, "SysDriver close offset");
static_assert(offsetof(SysDriver, scale) == 0x50, "SysDriver scale offset");
static_assert(offsetof(SysDriver, metric) == 0x60, "SysDriver metric offset");
static_assert(offsetof(SysDriver, glyphs_count) == 0x68, "SysDriver glyphs_count offset");
static_assert(offsetof(SysDriver, glyph_index) == 0x78, "SysDriver glyph_index offset");
static_assert(offsetof(SysDriver, set_char_with_dpi) == 0x80, "SysDriver set_char_with_dpi offset");
static_assert(offsetof(SysDriver, set_char_default_dpi) == 0x88,
"SysDriver set_char_default_dpi offset");
static_assert(offsetof(SysDriver, compute_layout) == 0xA0, "SysDriver compute_layout offset");
static_assert(offsetof(SysDriver, load_glyph_cached) == 0xA8, "SysDriver load_glyph_cached offset");
static_assert(offsetof(SysDriver, get_glyph_metrics) == 0xB8, "SysDriver get_glyph_metrics offset");
static_assert(offsetof(SysDriver, apply_glyph_adjust) == 0xE0,
"SysDriver apply_glyph_adjust offset");
static_assert(offsetof(SysDriver, configure_glyph) == 0x108, "SysDriver configure_glyph offset");
static_assert(offsetof(SysDriver, compute_layout_alt) == 0x118,
"SysDriver compute_layout_alt offset");
struct StyleStateBlock {
/*0x00*/ u32 dpi_x;
/*0x04*/ u32 dpi_y;
/*0x08*/ u32 scale_unit;
/*0x0C*/ u32 reserved_0x0c;
/*0x10*/ float scale_w;
/*0x14*/ float scale_h;
/*0x18*/ float effect_weight_x;
/*0x1C*/ float effect_weight_y;
/*0x20*/ float slant_ratio;
/*0x24*/ float reserved_0x24;
};
static_assert(sizeof(StyleStateBlock) == 0x28, "StyleStateBlock size");
static_assert(offsetof(StyleStateBlock, dpi_x) == 0x00, "StyleStateBlock dpi_x offset");
static_assert(offsetof(StyleStateBlock, dpi_y) == 0x04, "StyleStateBlock dpi_y offset");
static_assert(offsetof(StyleStateBlock, scale_unit) == 0x08, "StyleStateBlock scale_unit offset");
static_assert(offsetof(StyleStateBlock, scale_w) == 0x10, "StyleStateBlock scale_w offset");
static_assert(offsetof(StyleStateBlock, scale_h) == 0x14, "StyleStateBlock scale_h offset");
static_assert(offsetof(StyleStateBlock, effect_weight_x) == 0x18,
"StyleStateBlock effect_weight_x offset");
static_assert(offsetof(StyleStateBlock, effect_weight_y) == 0x1C,
"StyleStateBlock effect_weight_y offset");
static_assert(offsetof(StyleStateBlock, slant_ratio) == 0x20, "StyleStateBlock slant_ratio offset");
struct FontSetSelector {
static constexpr u32 kMagic = 0x53464C42u;
struct Candidate {
u32 font_id = 0xffffffffu;
FT_Face face = nullptr;
};
u32 magic = kMagic;
u32 font_set_type = 0;
void* library = nullptr;
u32 mode_low = 0;
u32 sub_font_index = 0;
u32 primary_font_id = 0xffffffffu;
u32 roman_font_id = 0xffffffffu;
u32 arabic_font_id = 0xffffffffu;
std::vector<Candidate> candidates;
};
struct FontSetRecordHeader {
/*0x00*/ u32 font_set_type;
/*0x04*/ u8 reserved_0x04[0x18];
/*0x1C*/ u32 magic;
/*0x20*/ u32 entry_count;
};
static_assert(sizeof(FontSetRecordHeader) == 0x24, "FontSetRecordHeader size");
static_assert(offsetof(FontSetRecordHeader, font_set_type) == 0x00,
"FontSetRecordHeader font_set_type offset");
static_assert(offsetof(FontSetRecordHeader, magic) == 0x1C, "FontSetRecordHeader magic offset");
static_assert(offsetof(FontSetRecordHeader, entry_count) == 0x20,
"FontSetRecordHeader entry_count offset");
struct FontSetRecordView {
const FontSetRecordHeader* header = nullptr;
const u32* entry_indices = nullptr;
const FontSetSelector* selector = nullptr;
};
inline std::size_t FontSetRecordSelectorOffset(u32 entry_count) {
const std::size_t indices_bytes = static_cast<std::size_t>(entry_count) * sizeof(u32);
const std::size_t ptr_off_unaligned = sizeof(FontSetRecordHeader) + indices_bytes;
const std::size_t ptr_align = alignof(const FontSetSelector*);
return (ptr_off_unaligned + (ptr_align - 1u)) & ~(ptr_align - 1u);
}
inline FontSetRecordView MakeFontSetRecordView(const FontSetRecordHeader* record) {
if (!record) {
return {};
}
FontSetRecordView view{};
view.header = record;
view.entry_indices = reinterpret_cast<const u32*>(static_cast<const void*>(record + 1));
const std::size_t ptr_off = FontSetRecordSelectorOffset(record->entry_count);
view.selector = *reinterpret_cast<const FontSetSelector* const*>(
static_cast<const void*>(reinterpret_cast<const u8*>(record) + ptr_off));
return view;
}
struct FontCtxHeader {
/*0x00*/ u32 lock_word;
/*0x04*/ u32 max_entries;
/*0x08*/ void* base;
/*0x10*/ u8 reserved_0x10[0x10];
};
static_assert(sizeof(FontCtxHeader) == 0x20, "FontCtxHeader size");
static_assert(offsetof(FontCtxHeader, lock_word) == 0x00, "FontCtxHeader lock_word offset");
static_assert(offsetof(FontCtxHeader, max_entries) == 0x04, "FontCtxHeader max_entries offset");
static_assert(offsetof(FontCtxHeader, base) == 0x08, "FontCtxHeader base offset");
struct FontCtxEntry {
/*0x00*/ u32 reserved_0x00;
/*0x04*/ u32 active;
/*0x08*/ u64 font_address;
/*0x10*/ u32 unique_id;
/*0x14*/ u32 lock_mode1;
/*0x18*/ u32 lock_mode3;
/*0x1C*/ u32 lock_mode2;
/*0x20*/ void* obj_mode1;
/*0x28*/ void* obj_mode3;
/*0x30*/ void* obj_mode2;
/*0x38*/ u8 reserved_0x38[0x08];
};
static_assert(sizeof(FontCtxEntry) == 0x40, "FontCtxEntry size");
static_assert(offsetof(FontCtxEntry, lock_mode1) == 0x14, "FontCtxEntry lock_mode1 offset");
static_assert(offsetof(FontCtxEntry, lock_mode3) == 0x18, "FontCtxEntry lock_mode3 offset");
static_assert(offsetof(FontCtxEntry, lock_mode2) == 0x1C, "FontCtxEntry lock_mode2 offset");
static_assert(offsetof(FontCtxEntry, obj_mode1) == 0x20, "FontCtxEntry obj_mode1 offset");
static_assert(offsetof(FontCtxEntry, obj_mode3) == 0x28, "FontCtxEntry obj_mode3 offset");
static_assert(offsetof(FontCtxEntry, obj_mode2) == 0x30, "FontCtxEntry obj_mode2 offset");
struct FontObj {
/*0x00*/ u32 refcount;
/*0x04*/ u32 reserved_0x04;
/*0x08*/ u32 reserved_0x08;
/*0x0C*/ u32 sub_font_index;
/*0x10*/ FontObj* prev;
/*0x18*/ FontObj* next;
/*0x20*/ u8 reserved_0x20[0x08];
/*0x28*/ void* open_ctx_0x28;
/*0x30*/ void* ft_face;
/*0x38*/ Libraries::Font::OrbisFontHandle font_handle;
/*0x40*/ s32 shift_units_x;
/*0x44*/ s32 shift_units_y;
/*0x48*/ std::uint64_t layout_seed_pair;
/*0x50*/ float scale_x_0x50;
/*0x54*/ float scale_y_0x54;
/*0x58*/ void* ft_ctx_0x58;
/*0x60*/ u8 reserved_0x60[0x04];
/*0x64*/ s32 cached_glyph_index_0x64;
/*0x68*/ std::uint64_t cached_units_x_0x68;
/*0x70*/ std::uint64_t cached_units_y_0x70;
/*0x78*/ s64 shift_cache_x;
/*0x80*/ s64 shift_cache_y;
/*0x88*/ std::array<std::uint64_t, 2> layout_seed_vec;
/*0x98*/ std::array<std::uint64_t, 2> layout_scale_vec;
/*0xA8*/ u8 reserved_0xA8[0x130 - 0xA8];
/*0x130*/ u32 glyph_cfg_word_0x130;
/*0x134*/ u8 glyph_cfg_mode_0x134;
/*0x135*/ u8 glyph_cfg_byte_0x135;
/*0x136*/ u8 glyph_cfg_byte_0x136;
/*0x137*/ u8 reserved_0x137[0x200 - 0x137];
};
static_assert(offsetof(FontObj, sub_font_index) == 0x0C, "FontObj sub_font_index offset");
static_assert(offsetof(FontObj, next) == 0x18, "FontObj next offset");
static_assert(offsetof(FontObj, ft_face) == 0x30, "FontObj ft_face offset");
static_assert(offsetof(FontObj, font_handle) == 0x38, "FontObj font_handle offset");
static_assert(offsetof(FontObj, shift_units_x) == 0x40, "FontObj shift_units_x offset");
static_assert(offsetof(FontObj, shift_units_y) == 0x44, "FontObj shift_units_y offset");
static_assert(offsetof(FontObj, layout_seed_pair) == 0x48, "FontObj layout_seed_pair offset");
static_assert(offsetof(FontObj, shift_cache_x) == 0x78, "FontObj shift_cache_x offset");
static_assert(offsetof(FontObj, shift_cache_y) == 0x80, "FontObj shift_cache_y offset");
static_assert(offsetof(FontObj, layout_seed_vec) == 0x88, "FontObj layout_seed_vec offset");
static_assert(offsetof(FontObj, layout_scale_vec) == 0x98, "FontObj layout_scale_vec offset");
static_assert(offsetof(FontObj, glyph_cfg_word_0x130) == 0x130, "FontObj glyph_cfg_word offset");
static_assert(sizeof(FontObj) == 0x200, "FontObj size");
struct SystemFontDefinition {
u32 font_set_type;
const char* config_key;
const char* default_file;
};
struct FontSetCache {
bool loaded = false;
bool available = false;
std::vector<unsigned char> bytes;
std::filesystem::path path;
};
struct FontLibOpaque {
u16 magic;
u16 reserved0;
u32 lock_word;
u32 flags;
u8 reserved1[0x14];
void* alloc_ctx;
void** alloc_vtbl;
u8 reserved2[0x50];
void* sys_driver;
void* fontset_registry;
union {
u8 reserved3[0x10];
std::array<std::uint64_t, 2> sysfonts_ctx_name_overrides;
};
void* sysfonts_ctx;
void* external_fonts_ctx;
u32* device_cache_buf;
};
static_assert(sizeof(FontLibOpaque) == 0xB8, "FontLibOpaque size");
static_assert(offsetof(FontLibOpaque, alloc_ctx) == 0x20, "FontLibOpaque alloc_ctx offset");
static_assert(offsetof(FontLibOpaque, alloc_vtbl) == 0x28, "FontLibOpaque alloc_vtbl offset");
static_assert(offsetof(FontLibOpaque, sys_driver) == 0x80, "FontLibOpaque sys_driver offset");
static_assert(offsetof(FontLibOpaque, fontset_registry) == 0x88,
"FontLibOpaque fontset_registry offset");
static_assert(offsetof(FontLibOpaque, sysfonts_ctx) == 0xA0, "FontLibOpaque sysfonts_ctx offset");
static_assert(offsetof(FontLibOpaque, external_fonts_ctx) == 0xA8,
"FontLibOpaque external_fonts_ctx offset");
static_assert(offsetof(FontLibOpaque, device_cache_buf) == 0xB0,
"FontLibOpaque device_cache_buf offset");
#pragma pack(push, 1)
struct FontLibReserved1Main {
/*0x00*/ u32 reserved_0x00;
/*0x04*/ u32 mem_kind;
/*0x08*/ u32 region_size;
/*0x0C*/ void* region_base;
};
#pragma pack(pop)
static_assert(sizeof(FontLibReserved1Main) == sizeof(((FontLibOpaque*)nullptr)->reserved1),
"FontLibReserved1Main size");
static_assert(offsetof(FontLibReserved1Main, mem_kind) == 0x04,
"FontLibReserved1Main mem_kind offset");
static_assert(offsetof(FontLibReserved1Main, region_size) == 0x08,
"FontLibReserved1Main region_size offset");
static_assert(offsetof(FontLibReserved1Main, region_base) == 0x0C,
"FontLibReserved1Main region_base offset");
struct FontLibReserved2Iface {
/*0x00*/ u8 reserved_00[0x20];
/*0x20*/ std::uintptr_t alloc_fn;
/*0x28*/ std::uintptr_t dealloc_fn;
/*0x30*/ std::uintptr_t realloc_fn;
/*0x38*/ std::uintptr_t calloc_fn;
/*0x40*/ u8 reserved_40[0x10];
};
static_assert(sizeof(FontLibReserved2Iface) == sizeof(((FontLibOpaque*)nullptr)->reserved2),
"FontLibReserved2Iface size");
static_assert(offsetof(FontLibReserved2Iface, alloc_fn) == 0x20,
"FontLibReserved2Iface alloc_fn offset");
static_assert(offsetof(FontLibReserved2Iface, dealloc_fn) == 0x28,
"FontLibReserved2Iface dealloc_fn offset");
static_assert(offsetof(FontLibReserved2Iface, realloc_fn) == 0x30,
"FontLibReserved2Iface realloc_fn offset");
static_assert(offsetof(FontLibReserved2Iface, calloc_fn) == 0x38,
"FontLibReserved2Iface calloc_fn offset");
struct FontLibTail {
/*0x00*/ u8 reserved_00[0x04];
/*0x04*/ u32 workspace_size;
/*0x08*/ void* workspace;
/*0x10*/ u8 reserved_10[0x10];
/*0x20*/ void* list_head_ptr;
/*0x28*/ Libraries::Font::OrbisFontHandle list_head;
/*0x30*/ u8 reserved_30[0x18];
};
static_assert(offsetof(FontLibTail, workspace_size) == 0x04, "FontLibTail workspace_size offset");
static_assert(offsetof(FontLibTail, workspace) == 0x08, "FontLibTail workspace offset");
static_assert(offsetof(FontLibTail, list_head_ptr) == 0x20, "FontLibTail list_head_ptr offset");
static_assert(offsetof(FontLibTail, list_head) == 0x28, "FontLibTail list_head offset");
static_assert(sizeof(FontLibTail) == 0x48, "FontLibTail size");
#pragma pack(push, 1)
struct FontLibReserved1SysfontTail {
/*0x00*/ u32 reserved_0x00;
/*0x04*/ void* sysfont_desc_ptr;
/*0x0C*/ u64 sysfont_flags;
};
#pragma pack(pop)
static_assert(sizeof(FontLibReserved1SysfontTail) == sizeof(((FontLibOpaque*)nullptr)->reserved1),
"FontLibReserved1SysfontTail size");
static_assert(offsetof(FontLibReserved1SysfontTail, sysfont_desc_ptr) == 0x04,
"FontLibReserved1SysfontTail sysfont_desc_ptr offset");
static_assert(offsetof(FontLibReserved1SysfontTail, sysfont_flags) == 0x0C,
"FontLibReserved1SysfontTail sysfont_flags offset");
struct RendererOpaque {
/*0x00*/ u16 magic;
/*0x02*/ u16 reserved02;
/*0x04*/ u8 reserved_04[0x08];
/*0x0C*/ u8 feature_byte_0x0c;
/*0x0D*/ u8 reserved_0d[0x03];
/*0x10*/ u32 mem_kind;
/*0x14*/ u32 region_size;
/*0x18*/ void* region_base;
/*0x20*/ void* alloc_ctx;
/*0x28*/ const OrbisFontMemInterface* mem_iface;
/*0x30*/ u8 reserved_30[0x20];
/*0x50*/ std::uintptr_t alloc_fn;
/*0x58*/ std::uintptr_t free_fn;
/*0x60*/ std::uintptr_t realloc_fn;
/*0x68*/ std::uintptr_t calloc_fn;
/*0x70*/ u8 reserved_70[0x10];
/*0x80*/ void* selection;
/*0x88*/ u8 reserved_88[0x08];
/*0x90*/ u64 outline_magic_0x90;
/*0x98*/ void* workspace;
/*0xA0*/ u64 workspace_size;
/*0xA8*/ u32 reserved_a8;
/*0xAC*/ u32 outline_policy_flag;
};
static_assert(sizeof(RendererOpaque) == 0xB0, "RendererOpaque size");
static_assert(offsetof(RendererOpaque, magic) == 0x00, "RendererOpaque magic offset");
static_assert(offsetof(RendererOpaque, feature_byte_0x0c) == 0x0C,
"RendererOpaque feature byte offset");
static_assert(offsetof(RendererOpaque, mem_kind) == 0x10, "RendererOpaque mem_kind offset");
static_assert(offsetof(RendererOpaque, region_size) == 0x14, "RendererOpaque region_size offset");
static_assert(offsetof(RendererOpaque, alloc_ctx) == 0x20, "RendererOpaque alloc_ctx offset");
static_assert(offsetof(RendererOpaque, mem_iface) == 0x28, "RendererOpaque mem_iface offset");
static_assert(offsetof(RendererOpaque, alloc_fn) == 0x50, "RendererOpaque alloc_fn offset");
static_assert(offsetof(RendererOpaque, free_fn) == 0x58, "RendererOpaque free_fn offset");
static_assert(offsetof(RendererOpaque, selection) == 0x80, "RendererOpaque selection offset");
static_assert(offsetof(RendererOpaque, workspace) == 0x98, "RendererOpaque workspace offset");
static_assert(offsetof(RendererOpaque, reserved_a8) == 0xA8, "RendererOpaque reserved_a8 offset");
static_assert(offsetof(RendererOpaque, outline_policy_flag) == 0xAC,
"RendererOpaque outline_policy_flag offset");
struct RendererFtBackend {
/*0x00*/ void* renderer_header_0x10;
/*0x08*/ std::uintptr_t unknown_0x08;
/*0x10*/ std::uintptr_t unknown_0x10;
/*0x18*/ std::uintptr_t unknown_0x18;
/*0x20*/ void* initialized_marker;
/*0x28*/ u8 reserved_0x28[0x20];
};
static_assert(sizeof(RendererFtBackend) == 0x48, "RendererFtBackend size");
static_assert(offsetof(RendererFtBackend, renderer_header_0x10) == 0x00,
"RendererFtBackend renderer_header_0x10 offset");
static_assert(offsetof(RendererFtBackend, initialized_marker) == 0x20,
"RendererFtBackend initialized_marker offset");
struct RendererFtOpaque {
/*0x000*/ RendererOpaque base;
/*0x0B0*/ u8 reserved_0x0B0[0x70];
/*0x120*/ RendererFtBackend ft_backend;
};
static_assert(sizeof(RendererFtOpaque) == 0x168, "RendererFtOpaque size");
static_assert(offsetof(RendererFtOpaque, ft_backend) == 0x120,
"RendererFtOpaque ft_backend offset");
struct OrbisFontRenderer_ {};
struct StyleFrameScaleState {
float scale_w;
float scale_h;
u32 dpi_x;
u32 dpi_y;
bool scale_overridden;
bool dpi_overridden;
};
extern const float kPointsPerInch;
extern const float kScaleEpsilon;
extern const u16 kStyleFrameMagic;
extern const u8 kStyleFrameFlagScale;
extern const u8 kStyleFrameFlagWeight;
extern const u8 kStyleFrameFlagSlant;
extern Core::FileSys::MntPoints* g_mnt;
extern std::unordered_map<Libraries::Font::OrbisFontHandle, FontState> g_font_state;
extern std::unordered_map<Libraries::Font::OrbisFontLib, LibraryState> g_library_state;
extern std::unordered_map<Libraries::Font::OrbisFontRenderSurface*,
const Libraries::Font::OrbisFontStyleFrame*>
g_style_for_surface;
extern std::mutex g_generated_glyph_mutex;
extern std::unordered_set<Libraries::Font::OrbisFontGlyph> g_generated_glyphs;
extern void* g_allocator_vtbl_stub[4];
extern std::uint8_t g_sys_driver_stub;
extern std::uint8_t g_fontset_registry_stub;
extern std::uint8_t g_sysfonts_ctx_stub;
extern std::uint8_t g_external_fonts_ctx_stub;
extern u32 g_device_cache_stub;
FontState& GetState(Libraries::Font::OrbisFontHandle h);
FontState* TryGetState(Libraries::Font::OrbisFontHandle h);
void RemoveState(Libraries::Font::OrbisFontHandle h);
LibraryState& GetLibState(Libraries::Font::OrbisFontLib lib);
void RemoveLibState(Libraries::Font::OrbisFontLib lib);
bool AcquireLibraryLock(FontLibOpaque* lib, u32& out_prev_lock_word);
void ReleaseLibraryLock(FontLibOpaque* lib, u32 prev_lock_word);
FT_Face CreateFreeTypeFaceFromBytes(const unsigned char* data, std::size_t size, u32 subfont_index);
void DestroyFreeTypeFace(FT_Face& face);
void LogFontOpenError(s32 rc);
void LogExternalFormatSupport(u32 formats_mask);
std::optional<std::filesystem::path> ResolveKnownSysFontAlias(
const std::filesystem::path& sysfonts_dir, std::string_view ps4_filename);
void LogFontOpenParams(const Libraries::Font::OrbisFontOpenParams* params);
std::filesystem::path ResolveGuestPath(const char* guest_path);
bool LoadGuestFileBytes(const std::filesystem::path& host_path,
std::vector<unsigned char>& out_bytes);
FaceMetrics LoadFaceMetrics(FT_Face face);
void PopulateStateMetrics(FontState& st, const FaceMetrics& m);
float ComputeScaleExtForState(const FontState& st, FT_Face face, float pixel_h);
float ComputeScaleForPixelHeight(const FontState& st, float pixel_h);
float SafeDpiToFloat(u32 dpi);
float PointsToPixels(float pt, u32 dpi);
float PixelsToPoints(float px, u32 dpi);
u16 ClampToU16(float value);
StyleFrameScaleState ResolveStyleFrameScale(const Libraries::Font::OrbisFontStyleFrame* style,
const FontState& st);
void InitializeStyleFrame(Libraries::Font::OrbisFontStyleFrame& frame);
bool EnsureStyleFrameInitialized(Libraries::Font::OrbisFontStyleFrame* frame);
bool ValidateStyleFramePtr(const Libraries::Font::OrbisFontStyleFrame* frame);
void UpdateCachedLayout(FontState& st);
std::uint64_t MakeGlyphKey(u32 code, int pixel_h);
void LogStrideOnce(const Libraries::Font::OrbisFontRenderSurface* surf);
void ClearRenderOutputs(Libraries::Font::OrbisFontGlyphMetrics* metrics,
Libraries::Font::OrbisFontRenderOutput* result);
bool ResolveFaceAndScale(FontState& st, Libraries::Font::OrbisFontHandle handle, float pixel_h,
FT_Face& face_out, float& scale_y_out);
bool ResolveFace(FontState& st, Libraries::Font::OrbisFontHandle handle, FT_Face& face_out);
s32 RenderCodepointToSurface(FontState& st, Libraries::Font::OrbisFontHandle handle, FT_Face face,
float pixel_w, float pixel_h,
Libraries::Font::OrbisFontRenderSurface* surf, u32 code, float x,
float y, Libraries::Font::OrbisFontGlyphMetrics* metrics,
Libraries::Font::OrbisFontRenderOutput* result, s32 shift_x_units,
s32 shift_y_units);
s32 RenderCodepointToSurfaceWithScale(FontState& st, Libraries::Font::OrbisFontHandle handle,
FT_Face face, float scale_x, float scale_y,
Libraries::Font::OrbisFontRenderSurface* surf, u32 code,
float x, float y, Libraries::Font::OrbisFontGlyphMetrics* m,
Libraries::Font::OrbisFontRenderOutput* result);
const GlyphEntry* GetGlyphEntry(FontState& st, Libraries::Font::OrbisFontHandle handle, u32 code,
FT_Face& face_out, float& scale_out);
const SystemFontDefinition* FindSystemFontDefinition(u32 font_set_type);
std::filesystem::path GetSysFontBaseDir();
std::filesystem::path ResolveSystemFontPath(u32 font_set_type);
const struct FontSetCache* EnsureFontSetCache(u32 font_set_type);
bool HasSfntTables(const std::vector<unsigned char>& bytes);
bool LoadFontFile(const std::filesystem::path& path, std::vector<unsigned char>& out_bytes);
bool AttachSystemFont(FontState& st, Libraries::Font::OrbisFontHandle handle);
std::string ReportSystemFaceRequest(FontState& st, Libraries::Font::OrbisFontHandle handle,
bool& attached_out);
void TrackGeneratedGlyph(Libraries::Font::OrbisFontGlyph glyph);
bool ForgetGeneratedGlyph(Libraries::Font::OrbisFontGlyph glyph);
GeneratedGlyph* TryGetGeneratedGlyph(Libraries::Font::OrbisFontGlyph glyph);
void PopulateGlyphMetricVariants(GeneratedGlyph& gg);
void BuildBoundingOutline(GeneratedGlyph& gg);
bool BuildTrueOutline(GeneratedGlyph& gg);
void LogCachedStyleOnce(Libraries::Font::OrbisFontHandle handle,
const Libraries::Font::FontHandleOpaqueNative& font);
void LogRenderResultSample(Libraries::Font::OrbisFontHandle handle, u32 code,
const Libraries::Font::OrbisFontGlyphMetrics& metrics,
const Libraries::Font::OrbisFontRenderOutput& result);
u8 CachedStyleCacheFlags(const Libraries::Font::OrbisFontStyleFrame& cached_style);
void CachedStyleSetCacheFlags(Libraries::Font::OrbisFontStyleFrame& cached_style, u8 flags);
void CachedStyleSetDirectionWord(Libraries::Font::OrbisFontStyleFrame& cached_style, u16 word);
float CachedStyleGetScalar(const Libraries::Font::OrbisFontStyleFrame& cached_style);
void CachedStyleSetScalar(Libraries::Font::OrbisFontStyleFrame& cached_style, float value);
} // namespace Libraries::Font::Internal

View File

@ -3,7 +3,10 @@
#include "common/logging/log.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/font/font.h"
#include "core/libraries/font/font_internal.h"
#include "core/libraries/font/fontft.h"
#include "core/libraries/font/fontft_internal.h"
#include "core/libraries/libs.h"
namespace Libraries::FontFt {
@ -103,14 +106,22 @@ s32 PS4_SYSV_ABI sceFontSelectGlyphsFt() {
return ORBIS_OK;
}
s32 PS4_SYSV_ABI sceFontSelectLibraryFt() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
const OrbisFontLibrarySelection* PS4_SYSV_ABI sceFontSelectLibraryFt(int value) {
LOG_INFO(Lib_FontFt, "called");
LOG_DEBUG(Lib_FontFt, "params:\nvalue: {}\n", value);
if (value == 0) {
return Libraries::FontFt::Internal::GetDriverTable();
}
return nullptr;
}
s32 PS4_SYSV_ABI sceFontSelectRendererFt() {
LOG_ERROR(Lib_FontFt, "(STUBBED) called");
return ORBIS_OK;
const OrbisFontRendererSelection* PS4_SYSV_ABI sceFontSelectRendererFt(int value) {
LOG_INFO(Lib_FontFt, "called");
LOG_DEBUG(Lib_FontFt, "params:\nvalue: {}\n", value);
if (value == 0) {
return Libraries::FontFt::Internal::GetRendererSelectionTable();
}
return nullptr;
}
void RegisterlibSceFontFt(Core::Loader::SymbolsResolver* sym) {
@ -137,4 +148,4 @@ void RegisterlibSceFontFt(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("Xx974EW-QFY", "libSceFontFt", 1, "libSceFontFt", sceFontSelectRendererFt);
};
} // namespace Libraries::FontFt
} // namespace Libraries::FontFt

View File

@ -11,6 +11,24 @@ class SymbolsResolver;
namespace Libraries::FontFt {
struct OrbisFontLibrarySelection {
u32 magic;
u32 reserved;
void* reserved_ptr1;
uintptr_t get_pixel_resolution_fn;
uintptr_t init_fn;
uintptr_t term_fn;
uintptr_t support_fn;
};
struct OrbisFontRendererSelection {
u32 magic;
u32 size;
uintptr_t create_fn;
uintptr_t destroy_fn;
uintptr_t query_fn;
};
s32 PS4_SYSV_ABI sceFontFtInitAliases();
s32 PS4_SYSV_ABI sceFontFtSetAliasFont();
s32 PS4_SYSV_ABI sceFontFtSetAliasPath();
@ -30,8 +48,8 @@ s32 PS4_SYSV_ABI sceFontFtSupportType42();
s32 PS4_SYSV_ABI sceFontFtSupportWinFonts();
s32 PS4_SYSV_ABI sceFontFtTermAliases();
s32 PS4_SYSV_ABI sceFontSelectGlyphsFt();
s32 PS4_SYSV_ABI sceFontSelectLibraryFt();
s32 PS4_SYSV_ABI sceFontSelectRendererFt();
const OrbisFontLibrarySelection* PS4_SYSV_ABI sceFontSelectLibraryFt(int value);
const OrbisFontRendererSelection* PS4_SYSV_ABI sceFontSelectRendererFt(int value);
void RegisterlibSceFontFt(Core::Loader::SymbolsResolver* sym);
} // namespace Libraries::FontFt
} // namespace Libraries::FontFt

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,778 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <bit>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_SYSTEM_H
#include "core/libraries/font/font.h"
#include "core/libraries/font/fontft.h"
namespace Libraries::Font {
struct FontHandleOpenInfo {
/*0x00*/ u32 unique_id_packed;
/*0x04*/ u32 ctx_entry_index;
/*0x08*/ u32 sub_font_index;
/*0x0C*/ u32 fontset_flags;
/*0x10*/ const void* fontset_record;
/*0x18*/ u64 reserved_0x18;
};
static_assert(sizeof(FontHandleOpenInfo) == 0x20, "FontHandleOpenInfo size");
static_assert(offsetof(FontHandleOpenInfo, sub_font_index) == 0x08,
"FontHandleOpenInfo sub_font_index offset");
static_assert(offsetof(FontHandleOpenInfo, fontset_record) == 0x10,
"FontHandleOpenInfo fontset_record offset");
struct FontHandleStyleStateTail {
/*0x00*/ u32 scale_unit;
/*0x04*/ u32 reserved_0x0c;
/*0x08*/ float scale_w;
/*0x0C*/ float scale_h;
/*0x10*/ float effect_weight_x;
/*0x14*/ float effect_weight_y;
/*0x18*/ float slant_ratio;
/*0x1C*/ float reserved_0x24;
};
static_assert(sizeof(FontHandleStyleStateTail) == 0x20, "FontHandleStyleStateTail size");
struct FontHandleOpaqueNative {
u16 magic;
u16 flags;
u32 lock_word;
FontHandleOpenInfo open_info;
OrbisFontLib library;
struct RendererBinding {
void* renderer;
u8 reserved_0x08[0x10 - sizeof(void*)];
};
static_assert(sizeof(RendererBinding) == 0x10, "RendererBinding size");
union {
u8 reserved_0x30[0x10];
RendererBinding renderer_binding;
};
u32 style_frame[2];
union {
u8 reserved_0x48[0x20];
FontHandleStyleStateTail style_tail;
};
OrbisFontStyleFrame cached_style;
u16 metricA;
u16 metricB;
u8 reserved_0xcc[0x1C];
u8 reserved_0xe8[0x08];
OrbisFontHandle prevFont;
OrbisFontHandle nextFont;
};
static_assert(sizeof(FontHandleOpaqueNative) == 0x100, "FontHandleOpaqueNative size");
static_assert(offsetof(FontHandleOpaqueNative, renderer_binding) == 0x30,
"FontHandleOpaqueNative renderer_binding offset");
static_assert(offsetof(FontHandleOpaqueNative, magic) == 0x00,
"FontHandleOpaqueNative magic offset");
static_assert(offsetof(FontHandleOpaqueNative, lock_word) == 0x04,
"FontHandleOpaqueNative lock_word offset");
static_assert(offsetof(FontHandleOpaqueNative, open_info) == 0x08,
"FontHandleOpaqueNative open_info offset");
static_assert(offsetof(FontHandleOpaqueNative, library) == 0x28,
"FontHandleOpaqueNative library offset");
static_assert(offsetof(FontHandleOpaqueNative, reserved_0x30) == 0x30,
"FontHandleOpaqueNative reserved_0x30 offset");
static_assert(offsetof(FontHandleOpaqueNative, style_frame) == 0x40,
"FontHandleOpaqueNative style_frame offset");
static_assert(offsetof(FontHandleOpaqueNative, reserved_0x48) == 0x48,
"FontHandleOpaqueNative reserved_0x48 offset");
static_assert(offsetof(FontHandleOpaqueNative, cached_style) == 0x68,
"FontHandleOpaqueNative cached_style offset");
static_assert(offsetof(FontHandleOpaqueNative, metricA) == 0xC8,
"FontHandleOpaqueNative metricA offset");
static_assert(offsetof(FontHandleOpaqueNative, metricB) == 0xCA,
"FontHandleOpaqueNative metricB offset");
static_assert(offsetof(FontHandleOpaqueNative, prevFont) == 0xF0,
"FontHandleOpaqueNative prev offset");
static_assert(offsetof(FontHandleOpaqueNative, nextFont) == 0xF8,
"FontHandleOpaqueNative next offset");
} // namespace Libraries::Font
namespace Libraries::Font::Internal {
struct alignas(16) LayoutWord {
std::array<u32, 4> words{};
constexpr u8* data() {
return reinterpret_cast<u8*>(words.data());
}
constexpr const u8* data() const {
return reinterpret_cast<const u8*>(words.data());
}
};
static_assert(sizeof(LayoutWord) == 16, "LayoutWord size");
static_assert(alignof(LayoutWord) == 16, "LayoutWord alignment");
struct alignas(16) HorizontalLayoutMetricsWord {
float line_advance = 0.0f;
float baseline = 0.0f;
float x_bound_lo = 0.0f;
float x_bound_hi = 0.0f;
};
static_assert(sizeof(HorizontalLayoutMetricsWord) == 16, "HorizontalLayoutMetricsWord size");
static_assert(alignof(HorizontalLayoutMetricsWord) == 16, "HorizontalLayoutMetricsWord alignment");
struct alignas(16) HorizontalLayoutEffectsWord {
u32 unknown_0x00 = 0;
u32 unknown_0x04 = 0;
float effect_height = 0.0f;
float packed_i8_adj_u13_lane1 = 0.0f;
};
static_assert(sizeof(HorizontalLayoutEffectsWord) == 16, "HorizontalLayoutEffectsWord size");
static_assert(alignof(HorizontalLayoutEffectsWord) == 16, "HorizontalLayoutEffectsWord alignment");
struct alignas(16) HorizontalLayoutAuxWord {
float packed_i8_adj_u13_lane0 = 0.0f;
u32 unknown_0x04 = 0;
u32 unknown_0x08 = 0;
u32 unknown_0x0C = 0;
};
static_assert(sizeof(HorizontalLayoutAuxWord) == 16, "HorizontalLayoutAuxWord size");
static_assert(alignof(HorizontalLayoutAuxWord) == 16, "HorizontalLayoutAuxWord alignment");
struct alignas(16) HorizontalLayoutBlocks {
HorizontalLayoutMetricsWord metrics;
HorizontalLayoutEffectsWord effects;
HorizontalLayoutAuxWord aux;
constexpr void* words() {
return &metrics;
}
constexpr const void* words() const {
return &metrics;
}
struct Values {
float line_advance = 0.0f;
float baseline = 0.0f;
float effect_height = 0.0f;
u64 x_bounds_bits = 0;
u64 i8_adj_u13_bits = 0;
};
float line_advance() const {
return metrics.line_advance;
}
float baseline() const {
return metrics.baseline;
}
float effect_height() const {
return effects.effect_height;
}
u64 x_bounds_bits() const {
return static_cast<u64>(std::bit_cast<u32>(metrics.x_bound_lo)) |
(static_cast<u64>(std::bit_cast<u32>(metrics.x_bound_hi)) << 32);
}
u64 i8_adj_u13_bits() const {
return static_cast<u64>(std::bit_cast<u32>(effects.packed_i8_adj_u13_lane1)) |
(static_cast<u64>(std::bit_cast<u32>(aux.packed_i8_adj_u13_lane0)) << 32);
}
Values values() const {
return {
.line_advance = line_advance(),
.baseline = baseline(),
.effect_height = effect_height(),
.x_bounds_bits = x_bounds_bits(),
.i8_adj_u13_bits = i8_adj_u13_bits(),
};
}
void set_line_advance(float v) {
metrics.line_advance = v;
}
void set_baseline(float v) {
metrics.baseline = v;
}
void set_x_bounds(float lo, float hi) {
metrics.x_bound_lo = lo;
metrics.x_bound_hi = hi;
}
void set_effect_height(float v) {
effects.effect_height = v;
}
void set_i8_adj_u13_lanes(float lane0, float lane1) {
aux.packed_i8_adj_u13_lane0 = lane0;
effects.packed_i8_adj_u13_lane1 = lane1;
}
};
static_assert(sizeof(HorizontalLayoutBlocks) == 0x30, "HorizontalLayoutBlocks size");
static_assert(alignof(HorizontalLayoutBlocks) == 16, "HorizontalLayoutBlocks alignment");
static_assert(offsetof(HorizontalLayoutBlocks, metrics) == 0x00,
"HorizontalLayoutBlocks metrics offset");
static_assert(offsetof(HorizontalLayoutBlocks, effects) == 0x10,
"HorizontalLayoutBlocks effects offset");
static_assert(offsetof(HorizontalLayoutBlocks, aux) == 0x20, "HorizontalLayoutBlocks aux offset");
struct alignas(16) VerticalLayoutMetricsWord {
float column_advance = 0.0f;
float baseline_offset_x = 0.0f;
float unknown_0x08 = 0.0f;
float unknown_0x0C = 0.0f;
};
static_assert(sizeof(VerticalLayoutMetricsWord) == 16, "VerticalLayoutMetricsWord size");
static_assert(alignof(VerticalLayoutMetricsWord) == 16, "VerticalLayoutMetricsWord alignment");
struct alignas(16) VerticalLayoutDecorationWord {
u32 unknown_0x00 = 0;
float decoration_span = 0.0f;
float unknown_0x08 = 0.0f;
float unknown_0x0C = 0.0f;
};
static_assert(sizeof(VerticalLayoutDecorationWord) == 16, "VerticalLayoutDecorationWord size");
static_assert(alignof(VerticalLayoutDecorationWord) == 16,
"VerticalLayoutDecorationWord alignment");
struct alignas(16) VerticalLayoutBlocks {
VerticalLayoutMetricsWord metrics;
VerticalLayoutDecorationWord decoration;
constexpr void* words() {
return &metrics;
}
constexpr const void* words() const {
return &metrics;
}
float column_advance() const {
return metrics.column_advance;
}
float baseline_offset_x() const {
return metrics.baseline_offset_x;
}
float decoration_span() const {
return decoration.decoration_span;
}
struct Values {
float column_advance = 0.0f;
float baseline_offset_x = 0.0f;
float decoration_span = 0.0f;
};
Values values() const {
return {
.column_advance = column_advance(),
.baseline_offset_x = baseline_offset_x(),
.decoration_span = decoration_span(),
};
}
void set_column_advance(float v) {
metrics.column_advance = v;
}
void set_baseline_offset_x(float v) {
metrics.baseline_offset_x = v;
}
void set_unknown_metrics_0x08(float v) {
metrics.unknown_0x08 = v;
}
void set_unknown_metrics_0x0C(float v) {
metrics.unknown_0x0C = v;
}
void set_decoration_span(float v) {
decoration.decoration_span = v;
}
void set_unknown_decoration_0x08(float v) {
decoration.unknown_0x08 = v;
}
void set_unknown_decoration_0x0C(float v) {
decoration.unknown_0x0C = v;
}
};
static_assert(sizeof(VerticalLayoutBlocks) == 0x20, "VerticalLayoutBlocks size");
static_assert(alignof(VerticalLayoutBlocks) == 16, "VerticalLayoutBlocks alignment");
static_assert(offsetof(VerticalLayoutBlocks, metrics) == 0x00,
"VerticalLayoutBlocks metrics offset");
static_assert(offsetof(VerticalLayoutBlocks, decoration) == 0x10,
"VerticalLayoutBlocks decoration offset");
struct HorizontalLayoutBlocksIo {
u8 (*words)[16] = nullptr;
struct F32Field {
u8* base = nullptr;
std::size_t offset = 0;
float value() const {
float v = 0.0f;
std::memcpy(&v, base + offset, sizeof(v));
return v;
}
F32Field& operator=(float v) {
std::memcpy(base + offset, &v, sizeof(v));
return *this;
}
operator float() const {
return value();
}
};
struct Fields {
F32Field line_advance;
F32Field baseline;
F32Field x_bound_0;
F32Field x_bound_1;
F32Field effect_height;
F32Field u13_i8_lane0;
F32Field u13_i8_lane1;
};
Fields fields() const {
return {
.line_advance = {words ? words[0] : nullptr, 0x00},
.baseline = {words ? words[0] : nullptr, 0x04},
.x_bound_0 = {words ? words[0] : nullptr, 0x08},
.x_bound_1 = {words ? words[0] : nullptr, 0x0C},
.effect_height = {words ? words[1] : nullptr, 0x08},
.u13_i8_lane0 = {words ? words[2] : nullptr, 0x00},
.u13_i8_lane1 = {words ? words[1] : nullptr, 0x0C},
};
}
};
struct VerticalLayoutBlocksIo {
u8 (*words)[16] = nullptr;
struct F32Field {
u8* base = nullptr;
std::size_t offset = 0;
float value() const {
float v = 0.0f;
std::memcpy(&v, base + offset, sizeof(v));
return v;
}
F32Field& operator=(float v) {
std::memcpy(base + offset, &v, sizeof(v));
return *this;
}
operator float() const {
return value();
}
};
struct Fields {
F32Field column_advance;
F32Field baseline_offset_x;
F32Field decoration_span;
F32Field unknown_metrics_0x08;
F32Field unknown_metrics_0x0C;
F32Field unknown_decoration_0x08;
F32Field unknown_decoration_0x0C;
};
Fields fields() const {
return {
.column_advance = {words ? words[0] : nullptr, 0x00},
.baseline_offset_x = {words ? words[0] : nullptr, 0x04},
.decoration_span = {words ? words[1] : nullptr, 0x04},
.unknown_metrics_0x08 = {words ? words[0] : nullptr, 0x08},
.unknown_metrics_0x0C = {words ? words[0] : nullptr, 0x0C},
.unknown_decoration_0x08 = {words ? words[1] : nullptr, 0x08},
.unknown_decoration_0x0C = {words ? words[1] : nullptr, 0x0C},
};
}
};
struct alignas(16) VerticalLayoutAltBlocks {
struct MetricsWord {
float unknown_0x00 = 0.0f;
float baseline_offset_x_candidate = 0.0f;
float unknown_0x08 = 0.0f;
float unknown_0x0C = 0.0f;
};
struct ExtrasWord {
float unknown_0x00 = 0.0f;
float decoration_span_candidate = 0.0f;
float unknown_0x08 = 0.0f;
float unknown_0x0C = 0.0f;
};
MetricsWord metrics;
ExtrasWord extras;
constexpr void* words() {
return &metrics;
}
constexpr const void* words() const {
return &metrics;
}
struct Values {
MetricsWord metrics{};
ExtrasWord extras{};
};
Values values() const {
return {
.metrics = metrics,
.extras = extras,
};
}
};
static_assert(sizeof(VerticalLayoutAltBlocks) == 0x20, "VerticalLayoutAltBlocks size");
static_assert(alignof(VerticalLayoutAltBlocks) == 16, "VerticalLayoutAltBlocks alignment");
static_assert(offsetof(VerticalLayoutAltBlocks, metrics) == 0x00,
"VerticalLayoutAltBlocks metrics offset");
static_assert(offsetof(VerticalLayoutAltBlocks, extras) == 0x10,
"VerticalLayoutAltBlocks extras offset");
struct GetCharGlyphMetricsFailLogState {
u32 count = 0;
bool suppression_logged = false;
};
struct SysFontRangeRecord {
/*0x00*/ u32 start;
/*0x04*/ u32 end;
/*0x08*/ s16 shift_x;
/*0x0A*/ s16 shift_y;
/*0x0C*/ float scale_mul;
/*0x10*/ u32 reserved_0x10;
/*0x14*/ u32 reserved_0x14;
/*0x18*/ u32 reserved_0x18;
};
static_assert(sizeof(SysFontRangeRecord) == 0x1C, "SysFontRangeRecord size");
static_assert(offsetof(SysFontRangeRecord, shift_x) == 0x08, "SysFontRangeRecord shift_x offset");
static_assert(offsetof(SysFontRangeRecord, scale_mul) == 0x0C,
"SysFontRangeRecord scale_mul offset");
struct F32x2 {
float lo = 0.0f;
float hi = 0.0f;
};
struct RenderSurfaceSystemUse {
Libraries::Font::OrbisFontStyleFrame* styleframe = nullptr;
float catchedScale = 0.0f;
std::uint8_t padding[88 - sizeof(Libraries::Font::OrbisFontStyleFrame*) - sizeof(float)]{};
};
static_assert(sizeof(RenderSurfaceSystemUse) ==
sizeof(((Libraries::Font::OrbisFontRenderSurface*)nullptr)->reserved_q),
"RenderSurfaceSystemUse layout must match OrbisFontRenderSurface::reserved_q");
s32 ComputeHorizontalLayoutBlocks(Libraries::Font::OrbisFontHandle fontHandle,
const void* style_state_block, u8 (*out_words)[16]);
s32 ComputeVerticalLayoutBlocks(Libraries::Font::OrbisFontHandle fontHandle,
const void* style_state_block, u8 (*out_words)[16]);
inline u8 (*LayoutWordsBytes(void* bytes))[16] {
return reinterpret_cast<u8(*)[16]>(bytes);
}
inline const u8 (*LayoutWordsBytes(const void* bytes))[16] {
return reinterpret_cast<const u8(*)[16]>(bytes);
}
inline s32 ComputeHorizontalLayoutBlocksWords(Libraries::Font::OrbisFontHandle fontHandle,
const void* style_state_block,
LayoutWord* out_words) {
return ComputeHorizontalLayoutBlocks(fontHandle, style_state_block,
reinterpret_cast<u8(*)[16]>(out_words));
}
inline s32 ComputeHorizontalLayoutBlocksTyped(Libraries::Font::OrbisFontHandle fontHandle,
const void* style_state_block,
HorizontalLayoutBlocks* out_blocks) {
return ComputeHorizontalLayoutBlocks(fontHandle, style_state_block,
reinterpret_cast<u8(*)[16]>(out_blocks->words()));
}
inline s32 ComputeVerticalLayoutBlocksWords(Libraries::Font::OrbisFontHandle fontHandle,
const void* style_state_block, LayoutWord* out_words) {
return ComputeVerticalLayoutBlocks(fontHandle, style_state_block,
reinterpret_cast<u8(*)[16]>(out_words));
}
inline s32 ComputeVerticalLayoutBlocksTyped(Libraries::Font::OrbisFontHandle fontHandle,
const void* style_state_block,
VerticalLayoutBlocks* out_blocks) {
return ComputeVerticalLayoutBlocks(fontHandle, style_state_block,
reinterpret_cast<u8(*)[16]>(out_blocks->words()));
}
inline s32 ComputeHorizontalLayoutBlocksToBytes(Libraries::Font::OrbisFontHandle fontHandle,
const void* style_state_block, void* out_bytes) {
return ComputeHorizontalLayoutBlocks(fontHandle, style_state_block,
LayoutWordsBytes(out_bytes));
}
inline s32 ComputeVerticalLayoutBlocksToBytes(Libraries::Font::OrbisFontHandle fontHandle,
const void* style_state_block, void* out_bytes) {
return ComputeVerticalLayoutBlocks(fontHandle, style_state_block, LayoutWordsBytes(out_bytes));
}
struct SysFontDesc {
float scale_factor;
s32 shift_value;
};
SysFontDesc GetSysFontDesc(u32 font_id);
Libraries::Font::FontHandleOpaqueNative* GetNativeFont(Libraries::Font::OrbisFontHandle h);
bool AcquireFontLock(Libraries::Font::FontHandleOpaqueNative* font, u32& out_prev_lock_word);
void ReleaseFontLock(Libraries::Font::FontHandleOpaqueNative* font, u32 prev_lock_word);
bool AcquireCachedStyleLock(Libraries::Font::FontHandleOpaqueNative* font, u32& out_prev_lock_word);
void ReleaseCachedStyleLock(Libraries::Font::FontHandleOpaqueNative* font, u32 prev_lock_word);
std::uint8_t* AcquireFontCtxEntry(std::uint8_t* ctx, u32 idx, u32 mode_low, void** out_obj,
u32* out_lock_word);
void ReleaseFontObjectsForHandle(Libraries::Font::OrbisFontHandle fontHandle, int entryCount);
s32 GetCharGlyphMetrics(Libraries::Font::OrbisFontHandle fontHandle, u32 code,
Libraries::Font::OrbisFontGlyphMetrics* metrics, bool use_cached_style);
const std::uint8_t* FindSysFontRangeRecord(u32 font_id, u32 codepoint);
u32 ResolveSysFontCodepoint(const void* record, u64 code, u32 flags, u32* out_font_id);
s32 RenderCharGlyphImageCore(Libraries::Font::OrbisFontHandle fontHandle, u32 code,
Libraries::Font::OrbisFontRenderSurface* surf, float x, float y,
Libraries::Font::OrbisFontGlyphMetrics* metrics,
Libraries::Font::OrbisFontRenderOutput* result);
s32 RenderGlyphImageCore(Libraries::Font::OrbisFontGlyph fontGlyph,
Libraries::Font::OrbisFontStyleFrame* fontStyleFrame,
Libraries::Font::OrbisFontRenderer fontRenderer,
Libraries::Font::OrbisFontRenderSurface* surface, float x, float y,
int mode, Libraries::Font::OrbisFontGlyphMetrics* metrics,
Libraries::Font::OrbisFontRenderOutput* result);
s32 StyleStateSetScalePixel(void* style_state_block, float w, float h);
s32 StyleStateSetScalePoint(void* style_state_block, float w, float h);
s32 StyleStateGetScalePixel(const void* style_state_block, float* w, float* h);
s32 StyleStateGetScalePoint(const void* style_state_block, float* w, float* h);
s32 StyleStateSetDpi(u32* dpi_pair, u32 h_dpi, u32 v_dpi);
s32 StyleStateSetSlantRatio(void* style_state_block, float slantRatio);
s32 StyleStateGetSlantRatio(const void* style_state_block, float* slantRatio);
s32 StyleStateSetWeightScale(void* style_state_block, float weightXScale, float weightYScale);
s32 StyleStateGetWeightScale(const void* style_state_block, float* weightXScale,
float* weightYScale, u32* mode);
} // namespace Libraries::Font::Internal
namespace Libraries::FontFt::Internal {
using GuestAllocFn = void*(PS4_SYSV_ABI*)(void* object, u32 size);
using GuestFreeFn = void(PS4_SYSV_ABI*)(void* object, void* p);
using GuestReallocFn = void*(PS4_SYSV_ABI*)(void* object, void* p, u32 size);
struct FtLibraryCtx {
void* alloc_ctx = nullptr;
void** alloc_vtbl = nullptr;
FT_Memory ft_memory = nullptr;
FT_Library ft_lib = nullptr;
};
struct BeU16 {
u8 b[2];
constexpr u16 value() const {
return static_cast<u16>((static_cast<u16>(b[0]) << 8) | static_cast<u16>(b[1]));
}
};
static_assert(sizeof(BeU16) == 2, "BeU16 size");
struct BeU32 {
u8 b[4];
constexpr u32 value() const {
return (static_cast<u32>(b[0]) << 24) | (static_cast<u32>(b[1]) << 16) |
(static_cast<u32>(b[2]) << 8) | static_cast<u32>(b[3]);
}
};
static_assert(sizeof(BeU32) == 4, "BeU32 size");
struct TtcHeader {
BeU32 tag;
BeU32 version;
BeU32 num_fonts;
};
static_assert(sizeof(TtcHeader) == 0x0C, "TtcHeader size");
struct SfntOffsetTable {
BeU32 version;
BeU16 num_tables;
BeU16 search_range;
BeU16 entry_selector;
BeU16 range_shift;
};
static_assert(sizeof(SfntOffsetTable) == 0x0C, "SfntOffsetTable size");
struct SfntTableRecord {
BeU32 tag;
BeU32 checksum;
BeU32 offset;
BeU32 length;
};
static_assert(sizeof(SfntTableRecord) == 0x10, "SfntTableRecord size");
struct FontObjSidecar {
const u8* font_data = nullptr;
u32 font_size = 0;
u32 sfnt_base = 0;
void* owned_data = nullptr;
};
struct LayoutOutIo {
u8 (*words)[16] = nullptr;
struct F32Field {
u8* base = nullptr;
std::size_t offset = 0;
F32Field& operator=(float v) {
std::memcpy(base + offset, &v, sizeof(v));
return *this;
}
};
struct Fields {
F32Field line_advance;
F32Field baseline;
F32Field x_bound_0;
F32Field x_bound_1;
F32Field max_advance_width;
F32Field hhea_caret_rise_adjust;
F32Field effect_height;
F32Field half_effect_width;
F32Field left_adjust;
};
Fields fields() const {
return {
.line_advance = {words[0], 0x00},
.baseline = {words[0], 0x04},
.x_bound_0 = {words[0], 0x08},
.x_bound_1 = {words[0], 0x0C},
.max_advance_width = {words[1], 0x00},
.hhea_caret_rise_adjust = {words[1], 0x04},
.effect_height = {words[1], 0x08},
.half_effect_width = {words[1], 0x0C},
.left_adjust = {words[2], 0x00},
};
}
};
struct LayoutAltOutIo {
u8 (*words)[16] = nullptr;
struct F32Field {
u8* base = nullptr;
std::size_t offset = 0;
F32Field& operator=(float v) {
std::memcpy(base + offset, &v, sizeof(v));
return *this;
}
};
struct Fields {
F32Field metrics_0x00;
F32Field metrics_0x04;
F32Field metrics_0x08;
F32Field metrics_0x0C;
F32Field adv_height;
F32Field effect_width;
F32Field slant_b;
F32Field slant_a;
};
Fields fields() const {
return {
.metrics_0x00 = {words[0], 0x00},
.metrics_0x04 = {words[0], 0x04},
.metrics_0x08 = {words[0], 0x08},
.metrics_0x0C = {words[0], 0x0C},
.adv_height = {words[1], 0x00},
.effect_width = {words[1], 0x04},
.slant_b = {words[1], 0x08},
.slant_a = {words[1], 0x0C},
};
}
};
const Libraries::FontFt::OrbisFontLibrarySelection* GetDriverTable();
const Libraries::FontFt::OrbisFontRendererSelection* GetRendererSelectionTable();
u32 PS4_SYSV_ABI LibraryGetPixelResolutionStub();
s32 PS4_SYSV_ABI LibraryInitStub(const void* memory, void* library);
s32 PS4_SYSV_ABI LibraryTermStub(void* library);
s32 PS4_SYSV_ABI LibrarySupportStub(void* library, u32 formats);
s32 PS4_SYSV_ABI LibraryOpenFontMemoryStub(void* library, u32 mode, const void* fontAddress,
u32 fontSize, u32 subFontIndex, u32 uniqueWord,
void** inoutFontObj);
s32 PS4_SYSV_ABI LibraryCloseFontObjStub(void* fontObj, u32 flags);
s32 PS4_SYSV_ABI LibraryGetFaceMetricStub(void* fontObj, u32 metricId, u16* outMetric);
s32 PS4_SYSV_ABI LibraryGetFaceScaleStub(void* fontObj, u16* outUnitsPerEm, float* outScale);
s32 PS4_SYSV_ABI LibraryGetGlyphIndexStub(void* fontObj, u32 codepoint_u16, u32* out_glyph_index);
s32 PS4_SYSV_ABI LibrarySetCharSizeWithDpiStub(void* fontObj, u32 dpi_x, u32 dpi_y, float scale_x,
float scale_y, float* out_scale_x,
float* out_scale_y);
s32 PS4_SYSV_ABI LibrarySetCharSizeDefaultDpiStub(void* fontObj, float scale_x, float scale_y,
float* out_scale_x, float* out_scale_y);
s32 PS4_SYSV_ABI LibraryComputeLayoutBlockStub(void* fontObj, const void* style_state_block,
u8 (*out_words)[16]);
s32 PS4_SYSV_ABI LibraryComputeLayoutAltBlockStub(void* fontObj, const void* style_state_block,
u8 (*out_words)[16]);
s32 PS4_SYSV_ABI LibraryLoadGlyphCachedStub(void* fontObj, u32 glyphIndex, s32 mode,
std::uint64_t* out_words);
s32 PS4_SYSV_ABI LibraryGetGlyphMetricsStub(void* fontObj, std::uint32_t* opt_param2,
std::uint8_t mode, std::uint8_t* out_params,
Libraries::Font::OrbisFontGlyphMetrics* out_metrics);
s32 PS4_SYSV_ABI LibraryApplyGlyphAdjustStub(void* fontObj, u32 p2, u32 glyphIndex, s32 p4, s32 p5,
u32* inoutGlyphIndex);
s32 PS4_SYSV_ABI LibraryConfigureGlyphStub(void* fontObj, std::uint32_t* in_params, s32 mode,
std::uint32_t* inout_state);
s32 PS4_SYSV_ABI FtRendererCreate(void* renderer);
u64 PS4_SYSV_ABI FtRendererQuery(void* renderer, u8* params, s64* out_ptr, u8 (*out_vec)[16]);
s32 PS4_SYSV_ABI FtRendererDestroy(void* renderer);
} // namespace Libraries::FontFt::Internal

View File

@ -12,6 +12,8 @@
#include "core/libraries/companion/companion_httpd.h"
#include "core/libraries/companion/companion_util.h"
#include "core/libraries/disc_map/disc_map.h"
#include "core/libraries/font/font.h"
#include "core/libraries/font/fontft.h"
#include "core/libraries/game_live_streaming/gamelivestreaming.h"
#include "core/libraries/gnmdriver/gnmdriver.h"
#include "core/libraries/hmd/hmd.h"
@ -151,6 +153,8 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::Voice::RegisterLib(sym);
Libraries::Rudp::RegisterLib(sym);
Libraries::VrTracker::RegisterLib(sym);
Libraries::Font::RegisterlibSceFont(sym);
Libraries::FontFt::RegisterlibSceFontFt(sym);
// Loading libSceSsl is locked behind a title workaround that currently applies to nothing.
// Libraries::Ssl::RegisterLib(sym);