diff options
author | 2016-03-16 19:42:01 +1100 | |
---|---|---|
committer | 2016-03-17 00:04:52 +1100 | |
commit | a3b35f8bc689901ac82a2d47bbe344a57c3632ba (patch) | |
tree | 0ffb561e756b9b46e1021dff80a16a410eab61a7 /src/osd/modules/font/font_sdl.cpp | |
parent | 7b7f2a3fb02c4515392b307ea04bb968450bdbbf (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.cpp | 199 |
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) |