summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/font/font_sdl.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2016-03-16 19:42:01 +1100
committer Vas Crabb <vas@vastheman.com>2016-03-17 00:04:52 +1100
commita3b35f8bc689901ac82a2d47bbe344a57c3632ba (patch)
tree0ffb561e756b9b46e1021dff80a16a410eab61a7 /src/osd/modules/font/font_sdl.cpp
parent7b7f2a3fb02c4515392b307ea04bb968450bdbbf (diff)
Move font enumeration to OSD, separate font name from display name as needed for OSX
Diffstat (limited to 'src/osd/modules/font/font_sdl.cpp')
-rw-r--r--src/osd/modules/font/font_sdl.cpp199
1 files changed, 115 insertions, 84 deletions
diff --git a/src/osd/modules/font/font_sdl.cpp b/src/osd/modules/font/font_sdl.cpp
index ace9963a28b..bbb3f7ba049 100644
--- a/src/osd/modules/font/font_sdl.cpp
+++ b/src/osd/modules/font/font_sdl.cpp
@@ -20,7 +20,6 @@
#include "corealloc.h"
#include "fileio.h"
-#define POINT_SIZE 144.0
//-------------------------------------------------
// font_open - attempt to "open" a handle to the
@@ -30,38 +29,53 @@
class osd_font_sdl : public osd_font
{
public:
- virtual ~osd_font_sdl() { }
+ osd_font_sdl() : m_font(nullptr) { }
+ osd_font_sdl(osd_font_sdl &&obj) : m_font(obj.m_font) { obj.m_font = nullptr; }
+ virtual ~osd_font_sdl() { close(); }
- virtual bool open(const char *font_path, const char *name, int &height);
+ virtual bool open(std::string const &font_path, std::string const &name, int &height);
virtual void close();
- virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs);
+ virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs);
+
+ osd_font_sdl & operator=(osd_font_sdl &&obj)
+ {
+ using std::swap;
+ swap(m_font, obj.m_font);
+ return *this;
+ }
+
private:
+ osd_font_sdl(osd_font_sdl const &) = delete;
+ osd_font_sdl & operator=(osd_font_sdl const &) = delete;
+
+ static constexpr double POINT_SIZE = 144.0;
+
#ifndef SDLMAME_HAIKU
- TTF_Font *search_font_config(std::string name, bool bold, bool italic, bool underline, bool &bakedstyles);
+ TTF_Font *search_font_config(std::string const &name, bool bold, bool italic, bool underline, bool &bakedstyles);
#endif
- bool BDF_Check_Magic(std::string name);
- TTF_Font * TTF_OpenFont_Magic(std::string name, int fsize);
+ bool BDF_Check_Magic(std::string const &name);
+ TTF_Font * TTF_OpenFont_Magic(std::string const &name, int fsize);
+
TTF_Font *m_font;
};
-bool osd_font_sdl::open(const char *font_path, const char *_name, int &height)
+bool osd_font_sdl::open(std::string const &font_path, std::string const &_name, int &height)
{
- TTF_Font *font = (TTF_Font *)NULL;
+ TTF_Font *font = nullptr;
bool bakedstyles = false;
int style = 0;
// accept qualifiers from the name
std::string name(_name);
-
- if (name.compare("default")==0)
+ if (name.compare("default") == 0)
{
name = "Liberation Sans";
}
- bool bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0);
- bool italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0);
- bool underline = (strreplace(name, "[U]", "") + strreplace(name, "[u]", "") > 0);
- bool strike = (strreplace(name, "[S]", "") + strreplace(name, "[s]", "") > 0);
+ bool const bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0);
+ bool const italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0);
+ bool const underline = (strreplace(name, "[U]", "") + strreplace(name, "[u]", "") > 0);
+ bool const strike = (strreplace(name, "[S]", "") + strreplace(name, "[s]", "") > 0);
// first up, try it as a filename
font = TTF_OpenFont_Magic(name, POINT_SIZE);
@@ -72,7 +86,7 @@ bool osd_font_sdl::open(const char *font_path, const char *_name, int &height)
{
osd_printf_verbose("Searching font %s in -%s\n", name.c_str(), OPTION_FONTPATH);
//emu_file file(options().font_path(), OPEN_FLAG_READ);
- emu_file file(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)
{
std::string full_name = file.fullpath();
@@ -96,7 +110,7 @@ bool osd_font_sdl::open(const char *font_path, const char *_name, int &height)
{
osd_printf_verbose("font %s is not TrueType or BDF, using MAME default\n", name.c_str());
}
- return NULL;
+ return false;
}
// apply styles
@@ -117,6 +131,7 @@ bool osd_font_sdl::open(const char *font_path, const char *_name, int &height)
height = TTF_FontLineSkip(font);
+ close();
m_font = font;
return true;
}
@@ -128,7 +143,9 @@ bool osd_font_sdl::open(const char *font_path, const char *_name, int &height)
void osd_font_sdl::close()
{
- TTF_CloseFont(this->m_font);
+ if (m_font)
+ TTF_CloseFont(m_font);
+ m_font = nullptr;
}
//-------------------------------------------------
@@ -139,17 +156,17 @@ void osd_font_sdl::close()
// pixel of a black & white font
//-------------------------------------------------
-bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs)
+bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs)
{
TTF_Font *ttffont;
SDL_Surface *drawsurf;
SDL_Color fcol = { 0xff, 0xff, 0xff };
- UINT16 ustr[16];
+ std::uint16_t ustr[16];
ttffont = m_font;
memset(ustr,0,sizeof(ustr));
- ustr[0] = (UINT16)chnum;
+ ustr[0] = (std::uint16_t)chnum;
drawsurf = TTF_RenderUNICODE_Solid(ttffont, ustr, fcol);
// was nothing returned?
@@ -161,8 +178,8 @@ bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &
// copy the rendered character image into it
for (int y = 0; y < bitmap.height(); y++)
{
- UINT32 *dstrow = &bitmap.pix32(y);
- UINT8 *srcrow = (UINT8 *)drawsurf->pixels;
+ std::uint32_t *dstrow = &bitmap.pix32(y);
+ std::uint8_t *srcrow = (std::uint8_t *)drawsurf->pixels;
srcrow += (y * drawsurf->pitch);
@@ -182,7 +199,7 @@ bool osd_font_sdl::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &
return bitmap.valid();
}
-TTF_Font * osd_font_sdl::TTF_OpenFont_Magic(std::string name, int fsize)
+TTF_Font * osd_font_sdl::TTF_OpenFont_Magic(std::string const &name, int fsize)
{
emu_file file(OPEN_FLAG_READ);
if (file.open(name.c_str()) == osd_file::error::NONE)
@@ -191,12 +208,12 @@ TTF_Font * osd_font_sdl::TTF_OpenFont_Magic(std::string name, int fsize)
unsigned char magic[5] = { 0x00, 0x01, 0x00, 0x00, 0x00 };
file.read(buffer,5);
if (memcmp(buffer, magic, 5))
- return NULL;
+ return nullptr;
}
return TTF_OpenFont(name.c_str(), POINT_SIZE);
}
-bool osd_font_sdl::BDF_Check_Magic(std::string name)
+bool osd_font_sdl::BDF_Check_Magic(std::string const &name)
{
emu_file file(OPEN_FLAG_READ);
if (file.open(name.c_str()) == osd_file::error::NONE)
@@ -213,54 +230,42 @@ bool osd_font_sdl::BDF_Check_Magic(std::string name)
}
#ifndef SDLMAME_HAIKU
-TTF_Font *osd_font_sdl::search_font_config(std::string name, bool bold, bool italic, bool underline, bool &bakedstyles)
+TTF_Font *osd_font_sdl::search_font_config(std::string const &name, bool bold, bool italic, bool underline, bool &bakedstyles)
{
- TTF_Font *font = (TTF_Font *)NULL;
- FcConfig *config;
- FcPattern *pat;
- FcObjectSet *os;
- FcFontSet *fontset;
+ TTF_Font *font = nullptr;
FcValue val;
- config = FcConfigGetCurrent();
- pat = FcPatternCreate();
- os = FcObjectSetCreate();
- FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.c_str());
+ 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());
// try and get a font with the requested styles baked-in
if (bold)
{
if (italic)
- {
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold Italic");
- }
+ FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Bold Italic");
else
- {
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Bold");
- }
+ FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Bold");
}
else if (italic)
{
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Italic");
+ FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Italic");
}
else
{
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular");
+ FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Regular");
}
- FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType");
+ FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
- FcObjectSetAdd(os, FC_FILE);
- fontset = FcFontList(config, pat, os);
+ FcObjectSetAdd(os.get(), FC_FILE);
+ std::unique_ptr<FcFontSet, void (*)(FcFontSet *)> fontset(FcFontList(config, pat.get(), os.get()), &FcFontSetDestroy);
for (int i = 0; i < fontset->nfont; i++)
{
- if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch)
- {
- continue;
- }
-
- if (val.type != FcTypeString)
+ if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch) ||
+ (val.type != FcTypeString))
{
continue;
}
@@ -281,43 +286,25 @@ TTF_Font *osd_font_sdl::search_font_config(std::string name, bool bold, bool ita
// didn't get a font above? try again with no baked-in styles
if (!font)
{
- FcPatternDestroy(pat);
- FcFontSetDestroy(fontset);
-
- pat = FcPatternCreate();
- FcPatternAddString(pat, FC_FAMILY, (const FcChar8 *)name.c_str());
- FcPatternAddString(pat, FC_STYLE, (const FcChar8 *)"Regular");
- FcPatternAddString(pat, FC_FONTFORMAT, (const FcChar8 *)"TrueType");
- fontset = FcFontList(config, pat, os);
+ pat.reset(FcPatternCreate());
+ FcPatternAddString(pat.get(), FC_FAMILY, (const FcChar8 *)name.c_str());
+ FcPatternAddString(pat.get(), FC_STYLE, (const FcChar8 *)"Regular");
+ FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
+ fontset.reset(FcFontList(config, pat.get(), os.get()));
- for (int i = 0; i < fontset->nfont; i++)
+ for (int i = 0; (i < fontset->nfont) && !font; i++)
{
- if (FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) != FcResultMatch)
+ if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) == FcResultMatch) &&
+ (val.type == FcTypeString))
{
- continue;
- }
+ osd_printf_verbose("Matching unstyled font: %s\n", val.u.s);
- if (val.type != FcTypeString)
- {
- continue;
- }
-
- osd_printf_verbose("Matching unstyled font: %s\n", val.u.s);
- {
- std::string match_name((const char*)val.u.s);
+ std::string const match_name((const char *)val.u.s);
font = TTF_OpenFont_Magic(match_name, POINT_SIZE);
}
-
- if (font)
- {
- break;
- }
}
}
- FcPatternDestroy(pat);
- FcObjectSetDestroy(os);
- FcFontSetDestroy(fontset);
return font;
}
#endif
@@ -330,9 +317,9 @@ public:
{
}
- osd_font *font_alloc()
+ osd_font::ptr font_alloc()
{
- return global_alloc(osd_font_sdl);
+ return std::make_unique<osd_font_sdl>();
}
virtual int init(const osd_options &options)
@@ -349,9 +336,53 @@ public:
{
TTF_Quit();
}
+
+ virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override;
};
+
+bool font_sdl::get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result)
+{
+ result.clear();
+
+ // TODO: enumerate TTF files in font path, since we can load them, too
+
+ FcConfig *const config = FcConfigGetCurrent();
+ std::unique_ptr<FcPattern, void (*)(FcPattern *)> pat(FcPatternCreate(), &FcPatternDestroy);
+ FcPatternAddString(pat.get(), FC_FONTFORMAT, (const FcChar8 *)"TrueType");
+
+ std::unique_ptr<FcObjectSet, void (*)(FcObjectSet *)> os(FcObjectSetCreate(), &FcObjectSetDestroy);
+ FcObjectSetAdd(os.get(), FC_FAMILY);
+ FcObjectSetAdd(os.get(), FC_FILE);
+
+ std::unique_ptr<FcFontSet, void (*)(FcFontSet *)> fontset(FcFontList(config, pat.get(), os.get()), &FcFontSetDestroy);
+ for (int i = 0; (i < fontset->nfont); i++)
+ {
+ FcValue val;
+ if ((FcPatternGet(fontset->fonts[i], FC_FILE, 0, &val) == FcResultMatch) &&
+ (val.type == FcTypeString) &&
+ (FcPatternGet(fontset->fonts[i], FC_FAMILY, 0, &val) == FcResultMatch) &&
+ (val.type == FcTypeString))
+ {
+ 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;
+ };
+ std::pair<std::string, std::string> font((const char *)val.u.s, (const char *)val.u.s);
+ 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));
+ }
+ }
+
+ return true;
+}
+
#else /* SDLMAME_UNIX */
- MODULE_NOT_SUPPORTED(font_sdl, OSD_FONT_PROVIDER, "sdl")
+
+MODULE_NOT_SUPPORTED(font_sdl, OSD_FONT_PROVIDER, "sdl")
+
#endif
MODULE_DEFINITION(FONT_SDL, font_sdl)