feat(font): keep a handle's script languages and typographic features
sceFontSetScriptLanguage, sceFontGetScriptLanguage, sceFontSetTypographicDesign and sceFontGetTypographicDesign threw. With the signatures SharpProspero declares, a font handle now keeps the language set for each script and the feature set for each typographic design, under the handle's lock, and returns them, with 0 for one never set. They do not change shaping or rendering yet; TechnicalDebt records the assumptions. Claude-Session: https://claude.ai/code/session_012SLQbhAiexxW6TtjYToW8a (cherry picked from commit c4dcbe4403dc635fde2a823dec311a939816cefc)
This commit is contained in:
parent
64baa79b65
commit
5ea89c7d4c
|
|
@ -7,6 +7,7 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
|
@ -28,6 +29,8 @@ struct FontState {
|
|||
FT_Face face = nullptr;
|
||||
float scaleW = 16.0f;
|
||||
float scaleH = 16.0f;
|
||||
std::map<int, int> scriptLanguages;
|
||||
std::map<int, int> typographicFeatures;
|
||||
|
||||
FontState() = default;
|
||||
FontState(const FontState&) = delete;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,30 @@ int ReadFontStyle(FontHandle fontHandle, bool checkMagic, Getter&& getter) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
template<typename Access>
|
||||
int AccessFontSettings(FontHandle fontHandle, Access&& access) {
|
||||
return ReadFontStyle(fontHandle, true, [&](FontHandleNative*) {
|
||||
FontState* state = TryGetState(fontHandle);
|
||||
return state ? access(*state) : SCE_FONT_ERROR_INVALID_FONT_HANDLE;
|
||||
});
|
||||
}
|
||||
|
||||
int SetFontSetting(FontHandle fontHandle, std::map<int, int> FontState::*table, int key, int value) {
|
||||
return AccessFontSettings(fontHandle, [&](FontState& state) {
|
||||
(state.*table)[key] = value;
|
||||
return SCE_FONT_OK;
|
||||
});
|
||||
}
|
||||
|
||||
int GetFontSetting(FontHandle fontHandle, std::map<int, int> FontState::*table, int key, int* value) {
|
||||
if (!value) return SCE_FONT_ERROR_INVALID_PARAMETER;
|
||||
return AccessFontSettings(fontHandle, [&](FontState& state) {
|
||||
const auto found = (state.*table).find(key);
|
||||
*value = found == (state.*table).end() ? 0 : found->second;
|
||||
return SCE_FONT_OK;
|
||||
});
|
||||
}
|
||||
|
||||
void ResetScaleOutputs(float* w, float* h) {
|
||||
if (w) *w = 0.0f;
|
||||
if (h) *h = 0.0f;
|
||||
|
|
@ -77,6 +101,22 @@ float ClampWeightDelta(float scale) {
|
|||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI sceFontSetScriptLanguage(FontHandle fontHandle, int fontScript, int fontLanguage) {
|
||||
return SetFontSetting(fontHandle, &FontState::scriptLanguages, fontScript, fontLanguage);
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontGetScriptLanguage(FontHandle fontHandle, int fontScript, int* fontLanguage) {
|
||||
return GetFontSetting(fontHandle, &FontState::scriptLanguages, fontScript, fontLanguage);
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontSetTypographicDesign(FontHandle fontHandle, int typographic, int feature) {
|
||||
return SetFontSetting(fontHandle, &FontState::typographicFeatures, typographic, feature);
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontGetTypographicDesign(FontHandle fontHandle, int typographic, int* feature) {
|
||||
return GetFontSetting(fontHandle, &FontState::typographicFeatures, typographic, feature);
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontSetScalePixel(FontHandle fontHandle, float w, float h) {
|
||||
return UpdateFontStyle(fontHandle, [&](FontHandleNative* font) {
|
||||
const int changed = StyleStateSetScalePixel(&font->style, w, h);
|
||||
|
|
|
|||
|
|
@ -88,16 +88,6 @@ int APS5_VABI sceFontGetGlyphExpandBufferState() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontGetScriptLanguage() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontGetTypographicDesign() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontGlyphGetAttribute() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
|
|
@ -368,16 +358,6 @@ int APS5_VABI sceFontGraphicsUpdateShapeFillPlot() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontSetScriptLanguage() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontSetTypographicDesign() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI sceFontSupportGlyphs() {
|
||||
NotImplemented_nid_no_patch(__func__);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ int APS5_VABI sceFontSupportExternalFonts(FontLibrary, std::uint32_t, std::uint3
|
|||
int APS5_VABI sceFontOpenFontSet(FontLibrary, std::uint32_t, std::uint32_t, const FontOpenDetail*, FontHandle*);
|
||||
int APS5_VABI sceFontOpenFontMemory(FontLibrary, const void*, std::uint32_t, const FontOpenDetail*, FontHandle*);
|
||||
int APS5_VABI sceFontCloseFont(FontHandle);
|
||||
int APS5_VABI sceFontSetScriptLanguage(FontHandle, int, int);
|
||||
int APS5_VABI sceFontGetScriptLanguage(FontHandle, int, int*);
|
||||
int APS5_VABI sceFontSetTypographicDesign(FontHandle, int, int);
|
||||
int APS5_VABI sceFontGetTypographicDesign(FontHandle, int, int*);
|
||||
int APS5_VABI sceFontSetResolutionDpi(FontHandle, std::uint32_t, std::uint32_t);
|
||||
int APS5_VABI sceFontGetResolutionDpi(FontHandle, std::uint32_t*, std::uint32_t*);
|
||||
int APS5_VABI sceFontSetScalePixel(FontHandle, float, float);
|
||||
|
|
@ -203,6 +207,17 @@ int main() {
|
|||
|
||||
const std::vector<unsigned char> fontData = EmptyGlyphFont();
|
||||
Require(sceFontOpenFontMemory(library, fontData.data(), static_cast<std::uint32_t>(fontData.size()), nullptr, &font) == SCE_FONT_OK && font != nullptr);
|
||||
int setting = -1;
|
||||
Require(sceFontGetScriptLanguage(font, 3, &setting) == SCE_FONT_OK && setting == 0);
|
||||
Require(sceFontSetScriptLanguage(font, 3, 7) == SCE_FONT_OK && sceFontSetScriptLanguage(font, 4, 9) == SCE_FONT_OK);
|
||||
Require(sceFontGetScriptLanguage(font, 3, &setting) == SCE_FONT_OK && setting == 7);
|
||||
Require(sceFontGetScriptLanguage(font, 4, &setting) == SCE_FONT_OK && setting == 9);
|
||||
Require(sceFontGetScriptLanguage(font, 3, nullptr) == SCE_FONT_ERROR_INVALID_PARAMETER);
|
||||
Require(sceFontSetScriptLanguage(nullptr, 3, 7) == SCE_FONT_ERROR_INVALID_FONT_HANDLE);
|
||||
Require(sceFontSetTypographicDesign(font, 1, 2) == SCE_FONT_OK);
|
||||
Require(sceFontGetTypographicDesign(font, 1, &setting) == SCE_FONT_OK && setting == 2);
|
||||
Require(sceFontGetTypographicDesign(font, 5, &setting) == SCE_FONT_OK && setting == 0);
|
||||
Require(sceFontGetTypographicDesign(nullptr, 1, &setting) == SCE_FONT_ERROR_INVALID_FONT_HANDLE);
|
||||
std::uint32_t hDpi = 1;
|
||||
std::uint32_t vDpi = 1;
|
||||
Require(sceFontGetResolutionDpi(font, &hDpi, &vDpi) == SCE_FONT_OK && hDpi == 72 && vDpi == 72);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ Throughout the project, every function at every stage either **does exactly what
|
|||
- [ulobjmgr](../../core/libs/prx/ulobjmgr/Export.cpp) registers no object: `_sceUlobjmgrRegisterObject` always hands out id 0 and `_sceUlobjmgrUnregisterObject` releases nothing, as shadPS4 does
|
||||
- [libSceHttp](../../core/libs/prx/libSceHttp/Export.cpp) - no request reaches the network, so `sceHttpSetResponseHeaderMaxSize` has no response header to limit, `sceHttpSetRecvBlockSize` (`(int id, u32 blockSize)` as in [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/network/http.h)) no response body to read in blocks and `sceHttpRedirectCacheFlush` no redirect to forget; `sceHttpsUnloadCert` returns success like `sceHttpsLoadCert`, which keeps no certificate; `sceHttpSetRedirectCallback` and `sceHttpSetCookieRecvCallback` accept callbacks that are never called, `sceHttpsSetSslVersion` has no TLS connection to configure and `sceHttpsGetSslError` reports error 0 with detail 0; `sceHttpSetAuthInfoCallback` accepts a callback that is never called, as no server asks for authentication
|
||||
- [sceFontGlyphDefineAttribute](../../core/libs/prx/libSceFont/src/Render.cpp) (libSceFont) checks the glyph and ignores the attribute and its value, whose meaning is unknown. PPSA01325 sets attribute 0x11 to 0 on a glyph from `sceFontGenerateCharGlyph` that it deletes unused, and draws the character with `sceFontRenderCharGlyphImageHorizontal`
|
||||
- [sceFontSetScriptLanguage, sceFontGetScriptLanguage, sceFontSetTypographicDesign, sceFontGetTypographicDesign](../../core/libs/prx/libSceFont/src/Style.cpp) (libSceFont) - signatures follow [SharpProspero](https://github.com/SvenGDK/SharpProspero/blob/main/src/SharpProspero/Interop/Font/SceFont.cs), not confirmed for the PS5. The handle keeps the language set for each script and the feature set for each typographic design and returns them, with 0 for one never set; the console default and its valid ranges are unknown, so any value is accepted. Neither setting changes shaping or rendering yet
|
||||
|
||||
### Unknown function info
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue