mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-09 03:01:28 -06:00
Merge 59d1c0d5aa into 13da5a82cc
This commit is contained in:
commit
61b3a131dc
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
10
externals/CMakeLists.txt
vendored
10
externals/CMakeLists.txt
vendored
@ -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
1
externals/freetype
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit b91f75bd02db43b06d634591eb286d3eb0ce3b65
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
1918
src/core/libraries/font/font_internal.cpp
Normal file
1918
src/core/libraries/font/font_internal.cpp
Normal file
File diff suppressed because it is too large
Load Diff
892
src/core/libraries/font/font_internal.h
Normal file
892
src/core/libraries/font/font_internal.h
Normal 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
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
3603
src/core/libraries/font/fontft_internal.cpp
Normal file
3603
src/core/libraries/font/fontft_internal.cpp
Normal file
File diff suppressed because it is too large
Load Diff
778
src/core/libraries/font/fontft_internal.h
Normal file
778
src/core/libraries/font/fontft_internal.h
Normal 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
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user