mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-12-03 11:11:25 +00:00
Merge pull request #18734 from hrydgard/more-sdl-fallback-font-work
SDL fallback fonts: Add more font names
This commit is contained in:
commit
97647a561d
@ -18,6 +18,18 @@
|
||||
#include "SDL2/SDL.h"
|
||||
#include "SDL2/SDL_ttf.h"
|
||||
|
||||
static std::string getlocale() {
|
||||
// setlocale is not an intuitive function...
|
||||
char *curlocale = setlocale(LC_CTYPE, nullptr);
|
||||
std::string loc = curlocale ? std::string(curlocale) : "en_US";
|
||||
size_t ptPos = loc.find('.');
|
||||
// Remove any secondary specifier.
|
||||
if (ptPos != std::string::npos) {
|
||||
loc.resize(ptPos);
|
||||
}
|
||||
return loc;
|
||||
}
|
||||
|
||||
TextDrawerSDL::TextDrawerSDL(Draw::DrawContext *draw): TextDrawer(draw) {
|
||||
if (TTF_Init() < 0) {
|
||||
ERROR_LOG(G3D, "Unable to initialize SDL2_ttf");
|
||||
@ -29,7 +41,7 @@ TextDrawerSDL::TextDrawerSDL(Draw::DrawContext *draw): TextDrawer(draw) {
|
||||
config = FcInitLoadConfigAndFonts();
|
||||
#endif
|
||||
|
||||
PrepareFallbackFonts();
|
||||
PrepareFallbackFonts(getlocale());
|
||||
}
|
||||
|
||||
TextDrawerSDL::~TextDrawerSDL() {
|
||||
@ -44,25 +56,56 @@ TextDrawerSDL::~TextDrawerSDL() {
|
||||
}
|
||||
|
||||
// If a user complains about missing characters on SDL, re-visit this!
|
||||
void TextDrawerSDL::PrepareFallbackFonts() {
|
||||
void TextDrawerSDL::PrepareFallbackFonts(std::string_view locale) {
|
||||
#if defined(USE_SDL2_TTF_FONTCONFIG)
|
||||
FcObjectSet *os = FcObjectSetBuild (FC_FILE, FC_INDEX, (char *) 0);
|
||||
|
||||
// To install the fallback font in ubuntu:
|
||||
// To install the recommended Droid Sans fallback font in Ubuntu:
|
||||
// sudo apt install fonts-droid-fallback
|
||||
const char *names[] = {
|
||||
"Droid Sans Fallback",
|
||||
const char *hardcodedNames[] = {
|
||||
"Droid Sans Medium",
|
||||
"Droid Sans Bold",
|
||||
"Droid Sans Fallback",
|
||||
"Source Han Sans Medium",
|
||||
"DejaVu Sans Condensed",
|
||||
"Noto Sans CJK Medium",
|
||||
"Noto Sans Hebrew Medium",
|
||||
"Noto Sans Lao Medium",
|
||||
"Noto Sans Thai Medium",
|
||||
"DejaVu Sans Condensed",
|
||||
"DejaVu Sans",
|
||||
"Meera Regular",
|
||||
"FreeSans",
|
||||
"Gargi",
|
||||
"KacstDigital",
|
||||
"KacstFarsi",
|
||||
"Khmer OS",
|
||||
"Paduak",
|
||||
"Paduak",
|
||||
"Jamrul",
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(names); i++) {
|
||||
std::vector<const char *> names;
|
||||
if (locale == "zh_CN") {
|
||||
names.push_back("Noto Sans CJK SC");
|
||||
} else if (locale == "zh_TW") {
|
||||
names.push_back("Noto Sans CJK TC");
|
||||
names.push_back("Noto Sans CJK HK");
|
||||
} else if (locale == "ja_JP") {
|
||||
names.push_back("Noto Sans CJK JP");
|
||||
} else if (locale == "ko_KR") {
|
||||
names.push_back("Noto Sans CJK KR");
|
||||
} else {
|
||||
// Let's just pick one.
|
||||
names.push_back("Noto Sans CJK JP");
|
||||
}
|
||||
|
||||
// Then push all the hardcoded ones.
|
||||
for (int i = 0; i < ARRAY_SIZE(hardcodedNames); i++) {
|
||||
names.push_back(hardcodedNames[i]);
|
||||
}
|
||||
|
||||
// First, add the region-specific Noto fonts according to the locale.
|
||||
|
||||
for (int i = 0; i < names.size(); i++) {
|
||||
// printf("trying font name %s\n", names[i]);
|
||||
FcPattern *name = FcNameParse((const FcChar8 *)names[i]);
|
||||
FcFontSet *foundFonts = FcFontList(config, name, os);
|
||||
@ -159,19 +202,25 @@ uint32_t TextDrawerSDL::CheckMissingGlyph(const std::string& text) {
|
||||
return missingGlyph;
|
||||
}
|
||||
|
||||
// If this returns true, the first font in fallbackFonts_ can be used as a fallback.
|
||||
bool TextDrawerSDL::FindFallbackFonts(uint32_t missingGlyph, int ptSize) {
|
||||
// If we encounter a missing glyph, try to use one of the fallback fonts.
|
||||
// If this returns >= 0, the nth font in fallbackFonts_ can be used as a fallback.
|
||||
int TextDrawerSDL::FindFallbackFonts(uint32_t missingGlyph, int ptSize) {
|
||||
auto iter = glyphFallbackFontIndex_.find(missingGlyph);
|
||||
|
||||
if (iter != glyphFallbackFontIndex_.end()) {
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
// If we encounter a missing glyph, try to use one of already loaded fallback fonts.
|
||||
for (int i = 0; i < fallbackFonts_.size(); i++) {
|
||||
TTF_Font *fallbackFont = fallbackFonts_[i];
|
||||
if (TTF_GlyphIsProvided32(fallbackFont, missingGlyph)) {
|
||||
fallbackFonts_.erase(fallbackFonts_.begin() + i);
|
||||
fallbackFonts_.insert(fallbackFonts_.begin(), fallbackFont);
|
||||
return true;
|
||||
glyphFallbackFontIndex_[missingGlyph] = i;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// If none of the loaded fonts can handle it, load more fonts.
|
||||
// TODO: Don't retry already tried fonts.
|
||||
for (int i = 0; i < fallbackFontPaths_.size(); i++) {
|
||||
std::string& fontPath = fallbackFontPaths_[i].first;
|
||||
int faceIndex = fallbackFontPaths_[i].second;
|
||||
@ -179,14 +228,16 @@ bool TextDrawerSDL::FindFallbackFonts(uint32_t missingGlyph, int ptSize) {
|
||||
TTF_Font *font = TTF_OpenFontIndex(fontPath.c_str(), ptSize, faceIndex);
|
||||
|
||||
if (TTF_GlyphIsProvided32(font, missingGlyph)) {
|
||||
fallbackFonts_.insert(fallbackFonts_.begin(), font);
|
||||
return true;
|
||||
fallbackFonts_.push_back(font);
|
||||
return fallbackFonts_.size() - 1;
|
||||
} else {
|
||||
TTF_CloseFont(font);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
// Not found at all? Let's remember that for this glyph.
|
||||
glyphFallbackFontIndex_[missingGlyph] = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t TextDrawerSDL::SetFont(const char *fontName, int size, int flags) {
|
||||
@ -234,13 +285,17 @@ void TextDrawerSDL::MeasureString(const char *str, size_t len, float *w, float *
|
||||
if (iter != sizeCache_.end()) {
|
||||
entry = iter->second.get();
|
||||
} else {
|
||||
printf("re-measuring %s\n", str);
|
||||
TTF_Font *font = fontMap_.find(fontHash_)->second;
|
||||
int ptSize = TTF_FontHeight(font) / 1.35;
|
||||
|
||||
uint32_t missingGlyph = CheckMissingGlyph(key.text);
|
||||
|
||||
if (missingGlyph && FindFallbackFonts(missingGlyph, ptSize)) {
|
||||
font = fallbackFonts_[0];
|
||||
if (missingGlyph) {
|
||||
int fallbackFont = FindFallbackFonts(missingGlyph, ptSize);
|
||||
if (fallbackFont >= 0) {
|
||||
font = fallbackFonts_[fallbackFont];
|
||||
}
|
||||
}
|
||||
|
||||
int width = 0;
|
||||
@ -270,8 +325,11 @@ void TextDrawerSDL::MeasureStringRect(const char *str, size_t len, const Bounds
|
||||
int ptSize = TTF_FontHeight(font) / 1.35;
|
||||
uint32_t missingGlyph = CheckMissingGlyph(toMeasure);
|
||||
|
||||
if (missingGlyph && FindFallbackFonts(missingGlyph, ptSize)) {
|
||||
font = fallbackFonts_[0];
|
||||
if (missingGlyph) {
|
||||
int fallbackFont = FindFallbackFonts(missingGlyph, ptSize);
|
||||
if (fallbackFont >= 0) {
|
||||
font = fallbackFonts_[fallbackFont];
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> lines;
|
||||
@ -381,8 +439,11 @@ void TextDrawerSDL::DrawStringBitmap(std::vector<uint8_t> &bitmapData, TextStrin
|
||||
|
||||
uint32_t missingGlyph = CheckMissingGlyph(processedStr);
|
||||
|
||||
if (missingGlyph && FindFallbackFonts(missingGlyph, ptSize)) {
|
||||
font = fallbackFonts_[0];
|
||||
if (missingGlyph) {
|
||||
int fallbackFont = FindFallbackFonts(missingGlyph, ptSize);
|
||||
if (fallbackFont >= 0) {
|
||||
font = fallbackFonts_[fallbackFont];
|
||||
}
|
||||
}
|
||||
|
||||
#if SDL_TTF_VERSION_ATLEAST(2, 20, 0)
|
||||
|
@ -28,9 +28,9 @@ public:
|
||||
|
||||
protected:
|
||||
void ClearCache() override;
|
||||
void PrepareFallbackFonts();
|
||||
void PrepareFallbackFonts(std::string_view locale);
|
||||
uint32_t CheckMissingGlyph(const std::string& text);
|
||||
bool FindFallbackFonts(uint32_t missingGlyph, int ptSize);
|
||||
int FindFallbackFonts(uint32_t missingGlyph, int ptSize);
|
||||
|
||||
uint32_t fontHash_;
|
||||
std::map<uint32_t, _TTF_Font *> fontMap_;
|
||||
@ -41,6 +41,8 @@ protected:
|
||||
std::vector<_TTF_Font *> fallbackFonts_;
|
||||
std::vector<std::pair<std::string, int>> fallbackFontPaths_; // path and font face index
|
||||
|
||||
std::map<int, int> glyphFallbackFontIndex_;
|
||||
|
||||
#if defined(USE_SDL2_TTF_FONTCONFIG)
|
||||
FcConfig *config;
|
||||
#endif
|
||||
|
@ -563,9 +563,9 @@ bool System_GetPropertyBool(SystemProperty prop) {
|
||||
#if PPSSPP_PLATFORM(SWITCH)
|
||||
case SYSPROP_HAS_TEXT_INPUT_DIALOG:
|
||||
return __nx_applet_type == AppletType_Application || __nx_applet_type != AppletType_SystemApplication;
|
||||
#endif
|
||||
case SYSPROP_HAS_KEYBOARD:
|
||||
return true;
|
||||
#endif
|
||||
case SYSPROP_APP_GOLD:
|
||||
#ifdef GOLD
|
||||
return true;
|
||||
|
@ -44,6 +44,7 @@ protected:
|
||||
void dialogFinished(const Screen *dialog, DialogResult result) override;
|
||||
|
||||
void CreateTabs() override;
|
||||
bool ShowSearchControls() const { return true; }
|
||||
|
||||
private:
|
||||
void PreCreateViews() override;
|
||||
|
Loading…
Reference in New Issue
Block a user