diff options
-rw-r--r-- | .gitignore | 8 | ||||
-rw-r--r-- | src/emu/rendfont.cpp | 26 | ||||
-rw-r--r-- | src/emu/rendfont.h | 6 | ||||
-rw-r--r-- | src/emu/ui/custui.cpp | 65 | ||||
-rw-r--r-- | src/emu/ui/custui.h | 29 | ||||
-rw-r--r-- | src/emu/ui/selector.cpp | 25 | ||||
-rw-r--r-- | src/emu/ui/selector.h | 3 | ||||
-rw-r--r-- | src/osd/modules/font/font_dwrite.cpp | 17 | ||||
-rw-r--r-- | src/osd/modules/font/font_module.h | 17 | ||||
-rw-r--r-- | src/osd/modules/font/font_none.cpp | 48 | ||||
-rw-r--r-- | src/osd/modules/font/font_osx.cpp | 139 | ||||
-rw-r--r-- | src/osd/modules/font/font_sdl.cpp | 199 | ||||
-rw-r--r-- | src/osd/modules/font/font_windows.cpp | 116 | ||||
-rw-r--r-- | src/osd/modules/lib/osdobj_common.cpp | 34 | ||||
-rw-r--r-- | src/osd/modules/lib/osdobj_common.h | 14 | ||||
-rw-r--r-- | src/osd/osdepend.h | 30 | ||||
-rw-r--r-- | src/osd/strconv.h | 16 |
17 files changed, 450 insertions, 342 deletions
diff --git a/.gitignore b/.gitignore index f01c2c01e05..5256e5fea85 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,9 @@ *~ +.*.sw? +*.pyc +*.pyo +.DS_Store + /* /*/ !/3rdparty/ @@ -30,11 +35,10 @@ /.idea regtests/chdman/temp regtests/jedutil/output -*.pyc *.mo /CMakeLists.txt /src/devices/cpu/m68000/m68kops.cpp /src/devices/cpu/m68000/m68kops.h /src/devices/cpu/m68000/m68kmake.* /src/devices/cpu/m68000/m68kmake -!/src/devices/cpu/m68000/m68kmake.cpp
\ No newline at end of file +!/src/devices/cpu/m68000/m68kmake.cpp diff --git a/src/emu/rendfont.cpp b/src/emu/rendfont.cpp index 27a14bb0d55..bcd1ca35d78 100644 --- a/src/emu/rendfont.cpp +++ b/src/emu/rendfont.cpp @@ -123,7 +123,7 @@ render_font::render_font(render_manager &manager, const char *filename) m_yoffs(0), m_scale(1.0f), m_rawsize(0), - m_osdfont(nullptr), + m_osdfont(), m_height_cmd(0), m_yoffs_cmd(0) { @@ -134,19 +134,18 @@ render_font::render_font(render_manager &manager, const char *filename) if (filename != nullptr) { m_osdfont = manager.machine().osd().font_alloc(); - if (m_osdfont != nullptr) + if (m_osdfont) { if (m_osdfont->open(manager.machine().options().font_path(), filename, m_height)) { - m_scale = 1.0f / (float)m_height; - m_format = FF_OSD; + m_scale = 1.0f / (float)m_height; + m_format = FF_OSD; - //mamep: allocate command glyph font - render_font_command_glyph(); - return; - } - global_free(m_osdfont); - m_osdfont = nullptr; + //mamep: allocate command glyph font + render_font_command_glyph(); + return; + } + m_osdfont.reset(); } } @@ -199,13 +198,6 @@ render_font::~render_font() } delete[] elem; } - - // release the OSD font - if (m_osdfont != nullptr) - { - m_osdfont->close(); - global_free(m_osdfont); - } } diff --git a/src/emu/rendfont.h b/src/emu/rendfont.h index 1f05babd789..b2ec2f12568 100644 --- a/src/emu/rendfont.h +++ b/src/emu/rendfont.h @@ -96,14 +96,14 @@ private: int m_height; // height of the font, from ascent to descent int m_yoffs; // y offset from baseline to descent float m_scale; // 1 / height precomputed - glyph *m_glyphs[256]; // array of glyph subtables + glyph *m_glyphs[256]; // array of glyph subtables std::vector<char> m_rawdata; // pointer to the raw data for the font UINT64 m_rawsize; // size of the raw font data - osd_font *m_osdfont; // handle to the OSD font + std::unique_ptr<osd_font> m_osdfont; // handle to the OSD font int m_height_cmd; // height of the font, from ascent to descent int m_yoffs_cmd; // y offset from baseline to descent - glyph *m_glyphs_cmd[256]; // array of glyph subtables + glyph *m_glyphs_cmd[256]; // array of glyph subtables std::vector<char> m_rawdata_cmd; // pointer to the raw data for the font // constants diff --git a/src/emu/ui/custui.cpp b/src/emu/ui/custui.cpp index a6279ac5b54..14f5cefc4b6 100644 --- a/src/emu/ui/custui.cpp +++ b/src/emu/ui/custui.cpp @@ -9,14 +9,16 @@ *********************************************************************/ #include "emu.h" +#include "ui/custui.h" + #include "ui/ui.h" -#include "ui/menu.h" #include "ui/selector.h" -#include "ui/custui.h" #include "ui/utils.h" + #include <algorithm> -const char *ui_menu_custom_ui::hide_status[] = { + +const char *const ui_menu_custom_ui::hide_status[] = { __("Show All"), __("Hide Filters"), __("Hide Info/Image"), @@ -192,24 +194,23 @@ void ui_menu_custom_ui::custom_render(void *selectedref, float top, float bottom ui_menu_font_ui::ui_menu_font_ui(running_machine &machine, render_container *container) : ui_menu(machine, container) { ui_options &moptions = machine.ui().options(); -#ifdef UI_WINDOWS - std::string name(machine.options().ui_font()); list(); +#ifdef UI_WINDOWS m_bold = (strreplace(name, "[B]", "") + strreplace(name, "[b]", "") > 0); m_italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0); +#endif m_actual = 0; for (size_t index = 0; index < m_fonts.size(); index++) { - if (m_fonts[index] == name) + if (m_fonts[index].first == name) { m_actual = index; break; } } -#endif m_info_size = moptions.infos_size(); m_font_size = moptions.font_rows(); @@ -231,43 +232,17 @@ ui_menu_font_ui::ui_menu_font_ui(running_machine &machine, render_container *con } -#ifdef UI_WINDOWS -//------------------------------------------------- -// fonts enumerator CALLBACK -//------------------------------------------------- - -int CALLBACK ui_menu_font_ui::EnumFontFamiliesExProc(const LOGFONT *lpelfe, const TEXTMETRIC *lpntme, DWORD FontType, LPARAM lParam) -{ - std::vector<std::string> *lpc = (std::vector<std::string>*)lParam; - std::string utf((char *)lpelfe->lfFaceName); - if (utf[0] != '@') - lpc->push_back(utf); - - return 1; -} - //------------------------------------------------- // create fonts list //------------------------------------------------- void ui_menu_font_ui::list() { - // create LOGFONT structure - LOGFONT lf; - lf.lfCharSet = ANSI_CHARSET; - lf.lfFaceName[0] = '\0'; - - HDC hDC = GetDC( nullptr ); - EnumFontFamiliesEx( hDC, &lf, (FONTENUMPROC)EnumFontFamiliesExProc, (LPARAM)&m_fonts, 0 ); - ReleaseDC( nullptr, hDC ); - - // sort - std::stable_sort(m_fonts.begin(), m_fonts.end()); + machine().osd().get_font_families(machine().options().font_path(), m_fonts); // add default string to the top of array - m_fonts.insert(m_fonts.begin(), std::string(_("default"))); + m_fonts.emplace(m_fonts.begin(), std::string("default"), std::string(_("default"))); } -#endif //------------------------------------------------- // dtor @@ -278,18 +253,18 @@ ui_menu_font_ui::~ui_menu_font_ui() std::string error_string; ui_options &moptions = machine().ui().options(); + std::string name(m_fonts[m_actual].first); #ifdef UI_WINDOWS - std::string name(m_fonts[m_actual]); - if (m_fonts[m_actual] != "default") + if (name != "default") { if (m_italic) name.insert(0, "[I]"); if (m_bold) name.insert(0, "[B]"); } +#endif machine().options().set_value(OPTION_UI_FONT, name.c_str(), OPTION_PRIORITY_CMDLINE, error_string); machine().options().mark_changed(OPTION_UI_FONT); -#endif moptions.set_value(OPTION_INFOS_SIZE, m_info_size, OPTION_PRIORITY_CMDLINE, error_string); moptions.set_value(OPTION_FONT_ROWS, m_font_size, OPTION_PRIORITY_CMDLINE, error_string); @@ -325,7 +300,6 @@ void ui_menu_font_ui::handle() } break; -#ifdef UI_WINDOWS case MUI_FNT: if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT) @@ -335,11 +309,15 @@ void ui_menu_font_ui::handle() } else if (m_event->iptkey == IPT_UI_SELECT) { - ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, m_fonts, m_actual)); + std::vector<std::string> display_names; + display_names.reserve(m_fonts.size()); + for (auto const &font : m_fonts) display_names.emplace_back(font.second); + ui_menu::stack_push(global_alloc_clear<ui_menu_selector>(machine(), container, std::move(display_names), m_actual)); changed = true; } break; +#ifdef UI_WINDOWS case MUI_BOLD: case MUI_ITALIC: if (m_event->iptkey == IPT_UI_LEFT || m_event->iptkey == IPT_UI_RIGHT || m_event->iptkey == IPT_UI_SELECT) @@ -364,13 +342,12 @@ void ui_menu_font_ui::populate() // set filter arrow UINT32 arrow_flags; -#ifdef UI_WINDOWS // add fonts option arrow_flags = get_arrow_flags(0, m_fonts.size() - 1, m_actual); - std::string name(m_fonts[m_actual]); - item_append(_("UI Font"), name.c_str(), arrow_flags, (void *)(FPTR)MUI_FNT); + item_append(_("UI Font"), m_fonts[m_actual].second.c_str(), arrow_flags, (void *)(FPTR)MUI_FNT); - if (name != "default") +#ifdef UI_WINDOWS + if (m_fonts[m_actual].first != "default") { item_append(_("Bold"), m_bold ? "On" : "Off", m_bold ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)MUI_BOLD); item_append(_("Italic"), m_italic ? "On" : "Off", m_italic ? MENU_FLAG_RIGHT_ARROW : MENU_FLAG_LEFT_ARROW, (void *)(FPTR)MUI_ITALIC); diff --git a/src/emu/ui/custui.h b/src/emu/ui/custui.h index 2ff13994cb6..46f42967b6a 100644 --- a/src/emu/ui/custui.h +++ b/src/emu/ui/custui.h @@ -10,13 +10,14 @@ #pragma once -#ifndef __UI_CUSTUI_H__ -#define __UI_CUSTUI_H__ +#ifndef MAME_EMU_UI_UI_CUSTUI_H +#define MAME_EMU_UI_UI_CUSTUI_H + +#include "ui/menu.h" + +#include <vector> +#include <string> -#ifdef UI_WINDOWS -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#endif //------------------------------------------------- // Custom UI menu @@ -39,9 +40,9 @@ private: COLORS_MENU, HIDE_MENU }; - static const char *hide_status[]; + static const char *const hide_status[]; std::vector<std::string> m_lang; - UINT16 m_currlang; + std::uint16_t m_currlang; }; //------------------------------------------------- @@ -67,14 +68,12 @@ private: MUI_ITALIC }; -#ifdef UI_WINDOWS - UINT16 m_actual; - std::vector<std::string> m_fonts; - bool m_bold, m_italic; - void list(); - static int CALLBACK EnumFontFamiliesExProc(const LOGFONT *lpelfe, const TEXTMETRIC *lpntme, DWORD FontType, LPARAM lParam); + std::uint16_t m_actual; + std::vector<std::pair<std::string, std::string> > m_fonts; +#ifdef UI_WINDOWS + bool m_bold, m_italic; #endif float m_info_min, m_info_max, m_info_size; @@ -182,4 +181,4 @@ private: rgb_t &m_original; }; -#endif /* __UI_CUSTUI_H__ */ +#endif // MAME_EMU_UI_UI_CUSTUI_H diff --git a/src/emu/ui/selector.cpp b/src/emu/ui/selector.cpp index 330694fd497..5f1704b79fe 100644 --- a/src/emu/ui/selector.cpp +++ b/src/emu/ui/selector.cpp @@ -18,13 +18,26 @@ // ctor / dtor //------------------------------------------------- -ui_menu_selector::ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> s_sel, UINT16 &s_actual, int category, int _hover) - : ui_menu(machine, container), m_selector(s_actual) +ui_menu_selector::ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> const &s_sel, UINT16 &s_actual, int category, int _hover) + : ui_menu(machine, container) + , m_selector(s_actual) + , m_category(category) + , m_hover(_hover) + , m_first_pass(true) + , m_str_items(s_sel) +{ + m_search[0] = '\0'; + m_searchlist[0] = nullptr; +} + +ui_menu_selector::ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> &&s_sel, UINT16 &s_actual, int category, int _hover) + : ui_menu(machine, container) + , m_selector(s_actual) + , m_category(category) + , m_hover(_hover) + , m_first_pass(true) + , m_str_items(std::move(s_sel)) { - m_category = category; - m_first_pass = true; - m_hover = _hover; - m_str_items = s_sel; m_search[0] = '\0'; m_searchlist[0] = nullptr; } diff --git a/src/emu/ui/selector.h b/src/emu/ui/selector.h index 595ca1f578d..b2ccba2a8b6 100644 --- a/src/emu/ui/selector.h +++ b/src/emu/ui/selector.h @@ -28,7 +28,8 @@ enum class ui_menu_selector : public ui_menu { public: - ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> _sel, UINT16 &_actual, int _category = 0, int _hover = 0); + ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> const &_sel, UINT16 &_actual, int _category = 0, int _hover = 0); + ui_menu_selector(running_machine &machine, render_container *container, std::vector<std::string> &&_sel, UINT16 &_actual, int _category = 0, int _hover = 0); virtual ~ui_menu_selector(); virtual void populate() override; virtual void handle() override; diff --git a/src/osd/modules/font/font_dwrite.cpp b/src/osd/modules/font/font_dwrite.cpp index cfcc952ef0d..0271aeaa249 100644 --- a/src/osd/modules/font/font_dwrite.cpp +++ b/src/osd/modules/font/font_dwrite.cpp @@ -345,7 +345,7 @@ public: { } - virtual bool open(const char *font_path, const char *_name, int &height) override + virtual bool open(std::string const &font_path, std::string const &_name, int &height) override { if (m_d2dfactory == nullptr || m_dwriteFactory == nullptr || m_wicFactory == nullptr) return false; @@ -359,11 +359,11 @@ public: bool italic = (strreplace(name, "[I]", "") + strreplace(name, "[i]", "") > 0); // convert the face name - auto familyName = std::wstring(std::unique_ptr<WCHAR, void(*)(void *)>(wstring_from_utf8(name.c_str()), osd_free).get()); + std::unique_ptr<WCHAR, void(*)(void *)> familyName(wstring_from_utf8(name.c_str()), osd_free); // find the font HR_RET0(find_font( - familyName.c_str(), + familyName.get(), bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, @@ -397,7 +397,7 @@ public: // pixel of a black & white font //------------------------------------------------- - virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) override + virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) override { const int MEM_ALIGN_CONST = 31; const int BITMAP_PAD = 50; @@ -714,9 +714,14 @@ public: return 0; } - virtual osd_font *font_alloc() override + virtual osd_font::ptr font_alloc() override { - return global_alloc(osd_font_dwrite(m_d2dfactory, m_dwriteFactory, m_wicFactory)); + return std::make_unique<osd_font_dwrite>(m_d2dfactory, m_dwriteFactory, m_wicFactory); + } + + virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override + { + return false; } }; diff --git a/src/osd/modules/font/font_module.h b/src/osd/modules/font/font_module.h index c9c7b1f40cb..81ffaca74e5 100644 --- a/src/osd/modules/font/font_module.h +++ b/src/osd/modules/font/font_module.h @@ -5,12 +5,16 @@ * */ -#ifndef FONT_MODULE_H_ -#define FONT_MODULE_H_ +#ifndef MAME_OSD_MODULES_FONT_FONTMODULE_H +#define MAME_OSD_MODULES_FONT_FONTMODULE_H #include "osdepend.h" #include "modules/osdmodule.h" +#include <string> +#include <vector> + + //============================================================ // CONSTANTS //============================================================ @@ -21,8 +25,13 @@ class font_module { public: virtual ~font_module() { } - virtual osd_font *font_alloc() = 0; + + /** attempt to allocate a font instance */ + virtual osd_font::ptr font_alloc() = 0; + + /** attempt to list available font families */ + virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) = 0; }; -#endif /* FONT_MODULE_H_ */ +#endif // MAME_OSD_MODULES_FONT_FONTMODULE_H diff --git a/src/osd/modules/font/font_none.cpp b/src/osd/modules/font/font_none.cpp index de9d01bb103..2716b52cf8e 100644 --- a/src/osd/modules/font/font_none.cpp +++ b/src/osd/modules/font/font_none.cpp @@ -8,61 +8,25 @@ #include "font_module.h" #include "modules/osdmodule.h" -//------------------------------------------------- -// font_open - attempt to "open" a handle to the -// font with the given name -//------------------------------------------------- - class osd_font_none : public osd_font { public: virtual ~osd_font_none() { } - virtual bool open(const char *font_path, const char *name, int &height) override; - virtual void close() override; - virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) override; + virtual bool open(std::string const &font_path, std::string const &name, int &height) override { return false; } + virtual void close() override { } + virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) override { return false; } }; -bool osd_font_none::open(const char *font_path, const char *_name, int &height) -{ - return false; -} - -//------------------------------------------------- -// font_close - release resources associated with -// a given OSD font -//------------------------------------------------- - -void osd_font_none::close() -{ -} - -//------------------------------------------------- -// font_get_bitmap - allocate and populate a -// BITMAP_FORMAT_ARGB32 bitmap containing the -// pixel values rgb_t(0xff,0xff,0xff,0xff) -// or rgb_t(0x00,0xff,0xff,0xff) for each -// pixel of a black & white font -//------------------------------------------------- - -bool osd_font_none::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) -{ - return false; -} - class font_none : public osd_module, public font_module { public: - font_none() : osd_module(OSD_FONT_PROVIDER, "none"), font_module() - { - } + font_none() : osd_module(OSD_FONT_PROVIDER, "none"), font_module() { } virtual int init(const osd_options &options) override { return 0; } - virtual osd_font *font_alloc() override - { - return global_alloc(osd_font_none); - } + virtual osd_font::ptr font_alloc() override { return std::make_unique<osd_font_none>(); } + virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override { return false; } }; MODULE_DEFINITION(FONT_NONE, font_none) diff --git a/src/osd/modules/font/font_osx.cpp b/src/osd/modules/font/font_osx.cpp index 831321fdf34..8e310714649 100644 --- a/src/osd/modules/font/font_osx.cpp +++ b/src/osd/modules/font/font_osx.cpp @@ -10,14 +10,11 @@ #ifdef SDLMAME_MACOSX -#include <Carbon/Carbon.h> - #include "corealloc.h" #include "fileio.h" -#define POINT_SIZE 144.0 -#define EXTRA_HEIGHT 1.0 -#define EXTRA_WIDTH 1.15 +#include <ApplicationServices/ApplicationServices.h> +#include <CoreFoundation/CoreFoundation.h> //------------------------------------------------- // font_open - attempt to "open" a handle to the @@ -27,48 +24,64 @@ class osd_font_osx : public osd_font { public: - virtual ~osd_font_osx() { } + osd_font_osx() : m_font(NULL) { } + osd_font_osx(osd_font_osx &&obj) : m_font(obj.m_font) { obj.m_font = NULL; } + virtual ~osd_font_osx() { 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_osx &operator=(osd_font_osx &&obj) + { + using std::swap; + swap(m_font, obj.m_font); + return *this; + } + private: + osd_font_osx(osd_font_osx const &) = delete; + osd_font_osx &operator=(osd_font_osx const &) = delete; + + static constexpr CGFloat POINT_SIZE = 144.0; + static constexpr CGFloat EXTRA_HEIGHT = 1.0; + static constexpr CGFloat EXTRA_WIDTH = 1.15; + CTFontRef m_font; }; -bool osd_font_osx::open(const char *font_path, const char *name, int &height) +bool osd_font_osx::open(std::string const &font_path, std::string const &name, int &height) { - m_font = NULL; - osd_printf_verbose("FONT NAME %s\n", name); + osd_printf_verbose("FONT NAME %s\n", name.c_str()); #if 0 - if (!strcmp(name, "default")) + if (name != "default") { name = "LucidaGrande"; } #endif - CFStringRef const font_name = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); - if (kCFNotFound != CFStringFind(font_name, CFSTR(".BDF"), kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareAnchored | kCFCompareNonliteral).location) + CFStringRef const font_name = CFStringCreateWithCString(NULL, name.c_str(), kCFStringEncodingUTF8); + if (font_name && (kCFNotFound != CFStringFind(font_name, CFSTR(".BDF"), kCFCompareCaseInsensitive | kCFCompareBackwards | kCFCompareAnchored | kCFCompareNonliteral).location)) { // handle bdf fonts in the core CFRelease(font_name); return false; } CTFontRef ct_font = NULL; - if (font_name != NULL) + if (font_name) { CTFontDescriptorRef const font_descriptor = CTFontDescriptorCreateWithNameAndSize(font_name, 0.0); - if (font_descriptor != NULL) + if (font_descriptor) { ct_font = CTFontCreateWithFontDescriptor(font_descriptor, POINT_SIZE, &CGAffineTransformIdentity); CFRelease(font_descriptor); } + CFRelease(font_name); } - CFRelease(font_name); if (!ct_font) { - osd_printf_verbose("Couldn't find/open font %s, using MAME default\n", name); + osd_printf_verbose("Couldn't find/open font %s, using MAME default\n", name.c_str()); return false; } @@ -84,6 +97,7 @@ bool osd_font_osx::open(const char *font_path, const char *name, int &height) line_height += CTFontGetLeading(ct_font); height = ceilf(line_height * EXTRA_HEIGHT); + close(); m_font = ct_font; return true; } @@ -96,9 +110,8 @@ bool osd_font_osx::open(const char *font_path, const char *name, int &height) void osd_font_osx::close() { if (m_font != NULL) - { CFRelease(m_font); - } + m_font = NULL; } //------------------------------------------------- @@ -109,7 +122,7 @@ void osd_font_osx::close() // pixel of a black & white font //------------------------------------------------- -bool osd_font_osx::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) +bool osd_font_osx::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) { UniChar uni_char; CGGlyph glyph; @@ -180,21 +193,89 @@ bool osd_font_osx::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 & class font_osx : public osd_module, public font_module { public: - font_osx() - : osd_module(OSD_FONT_PROVIDER, "osx"), font_module() + font_osx() : osd_module(OSD_FONT_PROVIDER, "osx"), font_module() { } + + virtual int init(const osd_options &options) override { return 0; } + virtual osd_font::ptr font_alloc() override { return std::make_unique<osd_font_osx>(); } + virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override; + +private: + static CFComparisonResult sort_callback(CTFontDescriptorRef first, CTFontDescriptorRef second, void *refCon) { + CFStringRef left = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(first, kCTFontDisplayNameAttribute, NULL); + if (!left) left = (CFStringRef)CTFontDescriptorCopyAttribute(first, kCTFontNameAttribute); + CFStringRef right = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(second, kCTFontDisplayNameAttribute, NULL); + if (!right) right = (CFStringRef)CTFontDescriptorCopyAttribute(second, kCTFontNameAttribute); + + CFComparisonResult result; + if (left && right) result = CFStringCompareWithOptions(left, right, CFRangeMake(0, CFStringGetLength(left)), kCFCompareCaseInsensitive | kCFCompareLocalized | kCFCompareNonliteral); + else if (!left) result = kCFCompareLessThan; + else if (!right) result = kCFCompareGreaterThan; + else result = kCFCompareEqualTo; + + if (left) CFRelease(left); + if (right) CFRelease(right); + return result; } +}; - virtual int init(const osd_options &options) { return 0; } - - osd_font *font_alloc() +bool font_osx::get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) +{ + CFStringRef keys[] = { kCTFontCollectionRemoveDuplicatesOption }; + std::uintptr_t values[ARRAY_LENGTH(keys)] = { 1 }; + CFDictionaryRef const options = CFDictionaryCreate(kCFAllocatorDefault, (void const **)keys, (void const **)values, ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, NULL); + CTFontCollectionRef const collection = CTFontCollectionCreateFromAvailableFonts(NULL); + CFRelease(options); + if (!collection) return false; + + CFArrayRef const descriptors = CTFontCollectionCreateMatchingFontDescriptorsSortedWithCallback(collection, &sort_callback, nullptr); + CFRelease(collection); + if (!descriptors) return false; + + result.clear(); + CFIndex const count = CFArrayGetCount(descriptors); + result.reserve(count); + for (CFIndex i = 0; i != count; i++) { - return global_alloc(osd_font_osx); + CTFontDescriptorRef const font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descriptors, i); + CFStringRef const name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontNameAttribute); + CFStringRef const display = (CFStringRef)CTFontDescriptorCopyLocalizedAttribute(font, kCTFontDisplayNameAttribute, NULL); + + if (name && display) + { + char const *utf; + std::vector<char> buf; + + utf = CFStringGetCStringPtr(name, kCFStringEncodingUTF8); + if (!utf) + { + buf.resize(CFStringGetMaximumSizeForEncoding(std::max(CFStringGetLength(name), CFStringGetLength(display)), kCFStringEncodingUTF8)); + CFStringGetCString(name, &buf[0], buf.size(), kCFStringEncodingUTF8); + } + std::string utf8name(utf ? utf : &buf[0]); + + utf = CFStringGetCStringPtr(display, kCFStringEncodingUTF8); + if (!utf) + { + buf.resize(CFStringGetMaximumSizeForEncoding(CFStringGetLength(display), kCFStringEncodingUTF8)); + CFStringGetCString(display, &buf[0], buf.size(), kCFStringEncodingUTF8); + } + std::string utf8display(utf ? utf : &buf[0]); + + result.emplace_back(std::move(utf8name), std::move(utf8display)); + } + + if (name) CFRelease(name); + if (display) CFRelease(display); } -}; + return true; +} + #else /* SDLMAME_MACOSX */ - MODULE_NOT_SUPPORTED(font_osx, OSD_FONT_PROVIDER, "osx") + +MODULE_NOT_SUPPORTED(font_osx, OSD_FONT_PROVIDER, "osx") + #endif MODULE_DEFINITION(FONT_OSX, font_osx) 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) diff --git a/src/osd/modules/font/font_windows.cpp b/src/osd/modules/font/font_windows.cpp index 6d561e5cddd..0de5231f8a0 100644 --- a/src/osd/modules/font/font_windows.cpp +++ b/src/osd/modules/font/font_windows.cpp @@ -5,49 +5,64 @@ * */ +#define WIN32_LEAN_AND_MEAN + #include "font_module.h" #include "modules/osdmodule.h" #if defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <commctrl.h> -#include <mmsystem.h> -#include <tchar.h> -#include <io.h> - #include "font_module.h" #include "modules/osdmodule.h" #include "strconv.h" #include "corestr.h" #include "corealloc.h" -#include "fileio.h" -//#define POINT_SIZE 144.0 -#define DEFAULT_FONT_HEIGHT (200) +#include <cstring> + +#include <windows.h> +#include <commctrl.h> +#include <mmsystem.h> +#include <tchar.h> +#include <io.h> -//------------------------------------------------- -// font_open - attempt to "open" a handle to the -// font with the given name -//------------------------------------------------- + +namespace { class osd_font_windows : public osd_font { public: osd_font_windows(): m_font(NULL) { } - virtual ~osd_font_windows() { } + osd_font_windows(osd_font_windows &&obj) : m_font(obj.m_font) { obj.m_font = NULL; } + virtual ~osd_font_windows() {close(); } - virtual bool open(const char *font_path, const char *name, int &height) override; + virtual bool open(std::string const &font_path, std::string const &name, int &height) override; virtual void close() override; - virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) override; + virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) override; + + osd_font_windows &operator=(osd_font_windows &&obj) + { + using std::swap; + swap(m_font, obj.m_font); + return *this; + } + private: + osd_font_windows(osd_font_windows const &) = delete; + osd_font_windows &operator=(osd_font_windows const &) = delete; + + //#define POINT_SIZE 144.0 + static constexpr LONG DEFAULT_HEIGHT = 200; + HGDIOBJ m_font; }; -bool osd_font_windows::open(const char *font_path, const char *_name, int &height) +bool osd_font_windows::open(std::string const &font_path, std::string const &_name, int &height) { + // don't leak a handle if we already have a font open + close(); + // accept qualifiers from the name std::string name(_name); if (name.compare("default")==0) name = "Tahoma"; @@ -56,7 +71,7 @@ bool osd_font_windows::open(const char *font_path, const char *_name, int &heigh // build a basic LOGFONT description of what we want LOGFONT logfont; - logfont.lfHeight = DEFAULT_FONT_HEIGHT; + logfont.lfHeight = DEFAULT_HEIGHT; logfont.lfWidth = 0; logfont.lfEscapement = 0; logfont.lfOrientation = 0; @@ -85,13 +100,19 @@ bool osd_font_windows::open(const char *font_path, const char *_name, int &heigh // select it into a temp DC and get the real font name HDC dummyDC = CreateCompatibleDC(NULL); HGDIOBJ oldfont = SelectObject(dummyDC, m_font); - TCHAR realname[100]; - GetTextFace(dummyDC, ARRAY_LENGTH(realname), realname); + std::vector<TCHAR> realname((std::max)(GetTextFace(dummyDC, 0, nullptr), 0)); + int facelen = GetTextFace(dummyDC, realname.size(), &realname[0]); SelectObject(dummyDC, oldfont); DeleteDC(dummyDC); + if (facelen <= 0) + { + DeleteObject(m_font); + m_font = NULL; + return false; + } // if it doesn't match our request, fail - char *utf = utf8_from_tstring(realname); + char *utf = utf8_from_tstring(&realname[0]); int result = core_stricmp(utf, name.c_str()); osd_free(utf); @@ -115,7 +136,7 @@ void osd_font_windows::close() // delete the font ojbect if (m_font != NULL) DeleteObject(m_font); - + m_font = NULL; } //------------------------------------------------- @@ -269,20 +290,51 @@ bool osd_font_windows::get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT class font_win : public osd_module, public font_module { public: - font_win() : osd_module(OSD_FONT_PROVIDER, "win"), font_module() - { - } + font_win() : osd_module(OSD_FONT_PROVIDER, "win"), font_module() { } virtual int init(const osd_options &options) override { return 0; } - virtual osd_font *font_alloc() override + virtual osd_font::ptr font_alloc() override { return std::make_unique<osd_font_windows>(); } + + virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override; + +private: + static int CALLBACK font_family_callback(LOGFONT const *lpelfe, TEXTMETRIC const *lpntme, DWORD FontType, LPARAM lParam) { - return global_alloc(osd_font_windows); + auto &result = *reinterpret_cast<std::vector<std::pair<std::string, std::string> > *>(lParam); + char *face = utf8_from_tstring(lpelfe->lfFaceName); + if ((*face != '@') && (result.empty() || (result.back().first != face))) result.emplace_back(face, face); + osd_free(face); + return TRUE; } - }; -#else /* SDLMAME_UNIX */ - MODULE_NOT_SUPPORTED(font_win, OSD_FONT_PROVIDER, "win") -#endif + + +bool font_win::get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) +{ + result.clear(); + + LOGFONT logfont; + std::memset(&logfont, 0, sizeof(logfont)); + logfont.lfCharSet = DEFAULT_CHARSET; + logfont.lfFaceName[0] = '\0'; + logfont.lfPitchAndFamily = 0; + + HDC dummyDC = CreateCompatibleDC(nullptr); + HRESULT err = EnumFontFamiliesEx(dummyDC, &logfont, &font_family_callback, reinterpret_cast<LPARAM>(&result), 0); + DeleteDC(dummyDC); + + std::stable_sort(result.begin(), result.end()); + + return !FAILED(err); +} + +} // anonymous namespace + +#else // defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) + +MODULE_NOT_SUPPORTED(font_win, OSD_FONT_PROVIDER, "win") + +#endif // defined(OSD_WINDOWS) || defined(SDLMAME_WIN32) MODULE_DEFINITION(FONT_WINDOWS, font_win) diff --git a/src/osd/modules/lib/osdobj_common.cpp b/src/osd/modules/lib/osdobj_common.cpp index 5cb7cb85da4..f85a322dc58 100644 --- a/src/osd/modules/lib/osdobj_common.cpp +++ b/src/osd/modules/lib/osdobj_common.cpp @@ -508,40 +508,6 @@ void osd_common_t::customize_input_type_list(simple_list<input_type_entry> &type //------------------------------------------------- -// font_open - attempt to "open" a handle to the -// font with the given name -//------------------------------------------------- - -osd_font *osd_common_t::font_open(const char *name, int &height) -{ - return nullptr; -} - - -//------------------------------------------------- -// font_close - release resources associated with -// a given OSD font -//------------------------------------------------- - -void osd_common_t::font_close(osd_font *font) -{ -} - - -//------------------------------------------------- -// font_get_bitmap - allocate and populate a -// BITMAP_FORMAT_ARGB32 bitmap containing the -// pixel values rgb_t(0xff,0xff,0xff,0xff) -// or rgb_t(0x00,0xff,0xff,0xff) for each -// pixel of a black & white font -//------------------------------------------------- - -bool osd_common_t::font_get_bitmap(osd_font *font, unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) -{ - return false; -} - -//------------------------------------------------- // get_slider_list - allocate and populate a // list of OS-dependent slider values. //------------------------------------------------- diff --git a/src/osd/modules/lib/osdobj_common.h b/src/osd/modules/lib/osdobj_common.h index 592391b5161..27e8d29d4a5 100644 --- a/src/osd/modules/lib/osdobj_common.h +++ b/src/osd/modules/lib/osdobj_common.h @@ -10,8 +10,8 @@ #pragma once -#ifndef __OSDOBJ_COMMON_H__ -#define __OSDOBJ_COMMON__ +#ifndef MAME_OSD_LIB_OSDOBJ_COMMON_H +#define MAME_OSD_LIB_OSDOBJ_COMMON_H #include "osdepend.h" #include "modules/osdmodule.h" @@ -182,18 +182,14 @@ public: // input overridables virtual void customize_input_type_list(simple_list<input_type_entry> &typelist) override; - // font overridables - virtual osd_font *font_open(const char *name, int &height); - virtual void font_close(osd_font *font); - virtual bool font_get_bitmap(osd_font *font, unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs); - // video overridables virtual slider_state *get_slider_list() override; // command option overrides virtual bool execute_command(const char *command) override; - virtual osd_font *font_alloc() override { return m_font_module->font_alloc(); } + virtual osd_font::ptr font_alloc() override { return m_font_module->font_alloc(); } + virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) override { return m_font_module->get_font_families(font_path, result); } virtual osd_midi_device *create_midi_device() override { return m_midi->create_midi_device(); } @@ -286,4 +282,4 @@ debug_module *osd_debugger_creator() return global_alloc(_DeviceClass()); } -#endif /* __OSDOBJ_COMMON_H__ */ +#endif // MAME_OSD_LIB_OSDOBJ_COMMON_H diff --git a/src/osd/osdepend.h b/src/osd/osdepend.h index 3e5b7d91e8f..b6ab45003e1 100644 --- a/src/osd/osdepend.h +++ b/src/osd/osdepend.h @@ -10,14 +10,18 @@ #pragma once -#ifndef __OSDEPEND_H__ -#define __OSDEPEND_H__ +#ifndef MAME_OSD_OSDEPEND_H +#define MAME_OSD_OSDEPEND_H #include "emucore.h" #include "osdcore.h" #include "unicode.h" #include "cliopts.h" +#include <memory> +#include <string> +#include <vector> + // forward references class input_type_entry; // FIXME: including emu.h does not work because emu.h includes osdepend.h @@ -32,11 +36,22 @@ class input_type_entry; // FIXME: including emu.h does not work because emu. class osd_font { public: - virtual ~osd_font() {} + typedef std::unique_ptr<osd_font> ptr; + + virtual ~osd_font() { } - virtual bool open(const char *font_path, const char *name, int &height) = 0; + /** attempt to "open" a handle to the font with the given name */ + virtual bool open(std::string const &font_path, std::string const &name, int &height) = 0; + + /** release resources associated with a given OSD font */ virtual void close() = 0; - virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, INT32 &width, INT32 &xoffs, INT32 &yoffs) = 0; + + /*! + * allocate and populate a BITMAP_FORMAT_ARGB32 bitmap containing + * the pixel values rgb_t(0xff,0xff,0xff,0xff) or + * rgb_t(0x00,0xff,0xff,0xff) for each pixel of a black & white font + */ + virtual bool get_bitmap(unicode_char chnum, bitmap_argb32 &bitmap, std::int32_t &width, std::int32_t &xoffs, std::int32_t &yoffs) = 0; }; // ======================> osd_interface @@ -68,7 +83,8 @@ public: virtual slider_state *get_slider_list() = 0; // font interface - virtual osd_font *font_alloc() = 0; + virtual osd_font::ptr font_alloc() = 0; + virtual bool get_font_families(std::string const &font_path, std::vector<std::pair<std::string, std::string> > &result) = 0; // command option overrides virtual bool execute_command(const char *command) = 0; @@ -80,4 +96,4 @@ protected: virtual ~osd_interface() { } }; -#endif /* __OSDEPEND_H__ */ +#endif // MAME_OSD_OSDEPEND_H diff --git a/src/osd/strconv.h b/src/osd/strconv.h index 5de23d0b89b..6d23d78fbb1 100644 --- a/src/osd/strconv.h +++ b/src/osd/strconv.h @@ -6,8 +6,8 @@ // //============================================================ -#ifndef __OSD_STRCONV__ -#define __OSD_STRCONV__ +#ifndef MAME_OSD_STRCONV_H +#define MAME_OSD_STRCONV_H #include "osdcore.h" @@ -17,12 +17,14 @@ // FUNCTION PROTOTYPES //============================================================ -#if defined(SDLMAME_WIN32) || defined(OSD_WINDOWS) +#if defined(WIN32) -#if defined(SDLMAME_WIN32) +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN -#include <windows.h> #endif + +#include <windows.h> + // the result of these functions has to be released with osd_free() CHAR *astring_from_utf8(const char *s); @@ -39,7 +41,7 @@ char *utf8_from_wstring(const WCHAR *s); #define utf8_from_tstring utf8_from_astring #endif // UNICODE -#endif //SDLMAME_WIN32 +#endif // defined(WIN32) -#endif // __OSD_STRCONV__ +#endif // MAME_OSD_STRCONV_H |