diff --git a/core/libs/prx/libSceFontFt/Export.cpp b/core/libs/prx/libSceFontFt/Export.cpp index d34a3ca559..0dcd8bcf90 100644 --- a/core/libs/prx/libSceFontFt/Export.cpp +++ b/core/libs/prx/libSceFontFt/Export.cpp @@ -1,11 +1,41 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include +#include +#include + +#include +#include FT_FREETYPE_H +#include FT_MODULE_H + #include "prx/libSceFontFt/include/FontFtDriver.hpp" #include "prx/libc/include/General.hpp" #pragma GCC visibility push(default) +namespace { + +FT_Library ProbeLibrary() { + static const FT_Library library = [] { + FT_Library created = nullptr; + if (FT_Init_FreeType(&created) != 0) return static_cast(nullptr); + return created; + }(); + return library; +} + +int SupportFormat(const char* function, std::initializer_list modules) { + const FT_Library library = ProbeLibrary(); + if (library == nullptr) throw std::runtime_error(std::string(function) + ": FreeType failed to initialize"); + for (const char* module : modules) { + if (FT_Get_Module(library, module) == nullptr) throw std::runtime_error(std::string(function) + ": FreeType module " + module + " is not built in"); + } + return 0; +} + +} + extern "C" { const Font::SysDriver* APS5_VABI sceFontSelectLibraryFt(int value) { @@ -32,13 +62,11 @@ int APS5_VABI sceFontFtSetAliasPath() { } int APS5_VABI sceFontFtSupportBdf() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"bdf"}); } int APS5_VABI sceFontFtSupportCid() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"t1cid"}); } int APS5_VABI sceFontFtSupportFontFormats() { @@ -47,28 +75,23 @@ int APS5_VABI sceFontFtSupportFontFormats() { } int APS5_VABI sceFontFtSupportOpenType() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"cff", "truetype"}); } int APS5_VABI sceFontFtSupportOpenTypeOtf() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"cff"}); } int APS5_VABI sceFontFtSupportOpenTypeTtf() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"truetype"}); } int APS5_VABI sceFontFtSupportPcf() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"pcf"}); } int APS5_VABI sceFontFtSupportPfr() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"pfr"}); } int APS5_VABI sceFontFtSupportSystemFonts() { @@ -77,8 +100,7 @@ int APS5_VABI sceFontFtSupportSystemFonts() { } int APS5_VABI sceFontFtSupportTrueType() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"truetype"}); } int APS5_VABI sceFontFtSupportTrueTypeGx() { @@ -87,18 +109,15 @@ int APS5_VABI sceFontFtSupportTrueTypeGx() { } int APS5_VABI sceFontFtSupportType1() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"type1"}); } int APS5_VABI sceFontFtSupportType42() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"type42"}); } int APS5_VABI sceFontFtSupportWinFonts() { - NotImplemented_nid_no_patch(__func__); - return 0; + return SupportFormat(__func__, {"winfonts"}); } int APS5_VABI sceFontFtTermAliases() { diff --git a/core/libs/tests/GuestFont.cpp b/core/libs/tests/GuestFont.cpp index fd90eb3349..427f8cf755 100644 --- a/core/libs/tests/GuestFont.cpp +++ b/core/libs/tests/GuestFont.cpp @@ -55,6 +55,17 @@ const FontWritingStep* APS5_VABI sceFontWritingRefersRenderStep(FontWriting*); FontTextCharacter* APS5_VABI sceFontWritingRefersRenderStepCharacter(FontWriting*, const FontWritingLetterStep**); const void* APS5_VABI sceFontSelectLibraryFt(int); const void* APS5_VABI sceFontSelectRendererFt(int); +int APS5_VABI sceFontFtSupportBdf(); +int APS5_VABI sceFontFtSupportCid(); +int APS5_VABI sceFontFtSupportOpenType(); +int APS5_VABI sceFontFtSupportOpenTypeOtf(); +int APS5_VABI sceFontFtSupportOpenTypeTtf(); +int APS5_VABI sceFontFtSupportPcf(); +int APS5_VABI sceFontFtSupportPfr(); +int APS5_VABI sceFontFtSupportTrueType(); +int APS5_VABI sceFontFtSupportType1(); +int APS5_VABI sceFontFtSupportType42(); +int APS5_VABI sceFontFtSupportWinFonts(); int APS5_VABI sceFontCharacterGetSyllableStringState(const FontTextCharacter*, int*); } @@ -168,6 +179,7 @@ int main() { Require(sceFontMemoryInit(&memory, nullptr, 0, &iface, nullptr, nullptr, nullptr) == SCE_FONT_OK); Require(sceFontSelectLibraryFt(0) != nullptr && sceFontSelectLibraryFt(1) == nullptr); Require(sceFontSelectRendererFt(0) != nullptr && sceFontSelectRendererFt(1) == nullptr); + Require(sceFontFtSupportBdf() == 0 && sceFontFtSupportCid() == 0 && sceFontFtSupportOpenType() == 0 && sceFontFtSupportOpenTypeOtf() == 0 && sceFontFtSupportOpenTypeTtf() == 0 && sceFontFtSupportPcf() == 0 && sceFontFtSupportPfr() == 0 && sceFontFtSupportTrueType() == 0 && sceFontFtSupportType1() == 0 && sceFontFtSupportType42() == 0 && sceFontFtSupportWinFonts() == 0); FontLibrary library = nullptr; Require(sceFontCreateLibrary(&memory, nullptr, &library) == SCE_FONT_ERROR_INVALID_PARAMETER && library == nullptr); diff --git a/docs/dev/debt/libSceFontFt.md b/docs/dev/debt/libSceFontFt.md new file mode 100644 index 0000000000..618ebd8322 --- /dev/null +++ b/docs/dev/debt/libSceFontFt.md @@ -0,0 +1,5 @@ +# libSceFontFt technical debt + +### Unknown function info + +- [sceFontFtSupportBdf, sceFontFtSupportCid, sceFontFtSupportOpenType, sceFontFtSupportOpenTypeOtf, sceFontFtSupportOpenTypeTtf, sceFontFtSupportPcf, sceFontFtSupportPfr, sceFontFtSupportTrueType, sceFontFtSupportType1, sceFontFtSupportType42 and sceFontFtSupportWinFonts](../../../core/libs/prx/libSceFontFt/Export.cpp) (libSceFontFt) are declared without parameters, signatures unknown; [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/font/fontft.cpp), another emulator, declares them the same way and only logs. They are assumed to enable one font format in the FontFt library, which here always registers FreeType's default modules, so each call returns 0 when the host FreeType has the module (`bdf`, `t1cid`, `truetype`, `cff`, `pcf`, `pfr`, `type1`, `type42`, `winfonts`; OpenType needs `cff` and `truetype`) and throws when it does not. The mapping of Sony's format names to FreeType modules, the return value and the error codes of the console are unverified, and no title is known to call them.