mirror of
https://github.com/holub/mame
synced 2025-06-05 20:33:45 +03:00
Implement couriersud's proposal to put style name in the config name for SDL fonts
Enumerate available font styles as well as families Still has a problem in that TTC fonts are enumerated but can't be loaded by SDL_ttf
This commit is contained in:
parent
f0e580e40a
commit
f99198c5c2
@ -57,7 +57,7 @@ private:
|
||||
static constexpr double POINT_SIZE = 144.0;
|
||||
|
||||
#if !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
|
||||
TTF_Font_ptr search_font_config(std::string const &name, bool bold, bool italic, bool underline, bool &bakedstyles);
|
||||
TTF_Font_ptr search_font_config(std::string const &family, std::string const &style, bool &bakedstyles);
|
||||
#endif
|
||||
bool BDF_Check_Magic(std::string const &name);
|
||||
TTF_Font_ptr TTF_OpenFont_Magic(std::string const &name, int fsize);
|
||||
@ -69,29 +69,29 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
|
||||
{
|
||||
bool bakedstyles = false;
|
||||
|
||||
// accept qualifiers from the name
|
||||
std::string name(_name);
|
||||
if (name.compare("default") == 0)
|
||||
{
|
||||
name = "Liberation Sans";
|
||||
name = "Liberation Sans|Regular";
|
||||
}
|
||||
|
||||
bool const bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0);
|
||||
bool const italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0);
|
||||
// accept qualifiers from the name
|
||||
bool const underline = (strreplace(name, "[U]", "") + strreplace(name, "[u]", "") > 0);
|
||||
bool const strike = (strreplace(name, "[S]", "") + strreplace(name, "[s]", "") > 0);
|
||||
std::string::size_type const separator = name.rfind('|');
|
||||
std::string const family(name.substr(0, separator));
|
||||
std::string const style((std::string::npos != separator) ? name.substr(separator + 1) : std::string());
|
||||
|
||||
// first up, try it as a filename
|
||||
TTF_Font_ptr font = TTF_OpenFont_Magic(name, POINT_SIZE);
|
||||
TTF_Font_ptr font = TTF_OpenFont_Magic(family, POINT_SIZE);
|
||||
|
||||
// if no success, try the font path
|
||||
|
||||
if (!font)
|
||||
{
|
||||
osd_printf_verbose("Searching font %s in -%s\n", name.c_str(), OPTION_FONTPATH);
|
||||
osd_printf_verbose("Searching font %s in -%s\n", family.c_str(), OPTION_FONTPATH);
|
||||
//emu_file file(options().font_path(), OPEN_FLAG_READ);
|
||||
emu_file file(font_path.c_str(), OPEN_FLAG_READ);
|
||||
if (file.open(name.c_str()) == osd_file::error::NONE)
|
||||
if (file.open(family.c_str()) == osd_file::error::NONE)
|
||||
{
|
||||
std::string full_name = file.fullpath();
|
||||
font = TTF_OpenFont_Magic(full_name, POINT_SIZE);
|
||||
@ -104,7 +104,7 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
|
||||
#if !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
|
||||
if (!font)
|
||||
{
|
||||
font = search_font_config(name, bold, italic, underline, bakedstyles);
|
||||
font = search_font_config(family, style, bakedstyles);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -118,21 +118,21 @@ bool osd_font_sdl::open(std::string const &font_path, std::string const &_name,
|
||||
}
|
||||
|
||||
// apply styles
|
||||
int style = 0;
|
||||
int styleflags = 0;
|
||||
if (!bakedstyles)
|
||||
{
|
||||
style |= bold ? TTF_STYLE_BOLD : 0;
|
||||
style |= italic ? TTF_STYLE_ITALIC : 0;
|
||||
if ((style.find("Bold") != std::string::npos) || (style.find("Black") != std::string::npos)) styleflags |= TTF_STYLE_BOLD;
|
||||
if ((style.find("Italic") != std::string::npos) || (style.find("Oblique") != std::string::npos)) styleflags |= TTF_STYLE_ITALIC;
|
||||
}
|
||||
style |= underline ? TTF_STYLE_UNDERLINE : 0;
|
||||
styleflags |= underline ? TTF_STYLE_UNDERLINE : 0;
|
||||
// SDL_ttf 2.0.9 and earlier does not define TTF_STYLE_STRIKETHROUGH
|
||||
#if SDL_VERSIONNUM(TTF_MAJOR_VERSION, TTF_MINOR_VERSION, TTF_PATCHLEVEL) > SDL_VERSIONNUM(2,0,9)
|
||||
style |= strike ? TTF_STYLE_STRIKETHROUGH : 0;
|
||||
styleflags |= strike ? TTF_STYLE_STRIKETHROUGH : 0;
|
||||
#else
|
||||
if (strike)
|
||||
osd_printf_warning("Ignoring strikethrough for SDL_TTF older than 2.0.10\n");
|
||||
#endif // PATCHLEVEL
|
||||
TTF_SetFontStyle(font.get(), style);
|
||||
TTF_SetFontStyle(font.get(), styleflags);
|
||||
|
||||
height = TTF_FontLineSkip(font.get());
|
||||
|
||||
@ -219,31 +219,18 @@ bool osd_font_sdl::BDF_Check_Magic(std::string const &name)
|
||||
}
|
||||
|
||||
#if !defined(SDLMAME_HAIKU) && !defined(SDLMAME_EMSCRIPTEN)
|
||||
osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &name, bool bold, bool italic, bool underline, bool &bakedstyles)
|
||||
osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &family, std::string const &style, bool &bakedstyles)
|
||||
{
|
||||
TTF_Font_ptr font(nullptr, &TTF_CloseFont);
|
||||
|
||||
FcConfig *const config = FcConfigGetCurrent();
|
||||
std::unique_ptr<FcPattern, void (*)(FcPattern *)> pat(FcPatternCreate(), &FcPatternDestroy);
|
||||
std::unique_ptr<FcObjectSet, void (*)(FcObjectSet *)> os(FcObjectSetCreate(), &FcObjectSetDestroy);
|
||||
FcPatternAddString(pat.get(), FC_FAMILY, (const FcChar8 *)name.c_str());
|
||||
FcPatternAddString(pat.get(), FC_FAMILY, (const FcChar8 *)family.c_str());
|
||||
|
||||
// try and get a font with the requested styles baked-in
|
||||
if (bold)
|
||||
{
|
||||
if (italic)
|
||||
FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Bold Italic");
|
||||
else
|
||||
FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Bold");
|
||||
}
|
||||
else if (italic)
|
||||
{
|
||||
FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Italic");
|
||||
}
|
||||
else
|
||||
{
|
||||
FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Regular");
|
||||
}
|
||||
if (!style.empty())
|
||||
FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)style.c_str());
|
||||
|
||||
FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
|
||||
|
||||
@ -266,12 +253,10 @@ osd_font_sdl::TTF_Font_ptr osd_font_sdl::search_font_config(std::string const &n
|
||||
}
|
||||
|
||||
// didn't get a font above? try again with no baked-in styles
|
||||
if (!font)
|
||||
if (!font && !style.empty())
|
||||
{
|
||||
pat.reset(FcPatternCreate());
|
||||
FcPatternAddString(pat.get(), FC_FAMILY, (const FcChar8 *)name.c_str());
|
||||
//Quite a lot of fonts don't have a "Regular" font type attribute
|
||||
//FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Regular");
|
||||
FcPatternAddString(pat.get(), FC_FAMILY, (const FcChar8 *)family.c_str());
|
||||
FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
|
||||
fontset.reset(FcFontList(config, pat.get(), os.get()));
|
||||
|
||||
@ -338,6 +323,7 @@ bool font_sdl::get_font_families(std::string const &font_path, std::vector<std::
|
||||
std::unique_ptr<FcObjectSet, void (*)(FcObjectSet *)> os(FcObjectSetCreate(), &FcObjectSetDestroy);
|
||||
FcObjectSetAdd(os.get(), FC_FAMILY);
|
||||
FcObjectSetAdd(os.get(), FC_FILE);
|
||||
FcObjectSetAdd(os.get(), FC_STYLE);
|
||||
|
||||
std::unique_ptr<FcFontSet, void (*)(FcFontSet *)> fontset(FcFontList(config, pat.get(), os.get()), &FcFontSetDestroy);
|
||||
for (int i = 0; (i < fontset->nfont); i++)
|
||||
@ -350,19 +336,30 @@ bool font_sdl::get_font_families(std::string const &font_path, std::vector<std::
|
||||
{
|
||||
auto const compare_fonts = [](std::pair<std::string, std::string> const &a, std::pair<std::string, std::string> const &b) -> bool
|
||||
{
|
||||
int const first = core_stricmp(a.first.c_str(), b.first.c_str());
|
||||
if (first < 0) return true;
|
||||
else if (first > 0) return false;
|
||||
else return core_stricmp(b.second.c_str(), b.second.c_str()) < 0;
|
||||
int const second = core_stricmp(a.second.c_str(), b.second.c_str());
|
||||
if (second < 0) return true;
|
||||
else if (second > 0) return false;
|
||||
else return core_stricmp(b.first.c_str(), b.first.c_str()) < 0;
|
||||
};
|
||||
std::pair<std::string, std::string> font((const char *)val.u.s, (const char *)val.u.s);
|
||||
std::string config((const char *)val.u.s);
|
||||
std::string display(config);
|
||||
if ((FcPatternGet(fontset->fonts[i], FC_STYLE, 0, &val) == FcResultMatch) && (val.type == FcTypeString))
|
||||
{
|
||||
config.push_back('|');
|
||||
config.append((const char *)val.u.s);
|
||||
display.push_back(' ');
|
||||
display.append((const char *)val.u.s);
|
||||
}
|
||||
std::pair<std::string, std::string> font(std::move(config), std::move(display));
|
||||
auto const pos = std::lower_bound(result.begin(), result.end(), font, compare_fonts);
|
||||
if ((result.end() == pos) || (pos->first != font.first)) result.emplace(pos, std::move(font));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* SDLMAME_UNIX */
|
||||
|
Loading…
Reference in New Issue
Block a user