mirror of
https://github.com/holub/mame
synced 2025-06-04 11:56:28 +03:00
Move font enumeration to OSD, separate font name from display name as needed for OSX
This commit is contained in:
parent
7b7f2a3fb0
commit
a3b35f8bc6
8
.gitignore
vendored
8
.gitignore
vendored
@ -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
|
||||
!/src/devices/cpu/m68000/m68kmake.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -9,14 +9,16 @@
|
||||
*********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "ui/ui.h"
|
||||
#include "ui/menu.h"
|
||||
#include "ui/selector.h"
|
||||
#include "ui/custui.h"
|
||||
|
||||
#include "ui/ui.h"
|
||||
#include "ui/selector.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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
{
|
||||
return global_alloc(osd_font_osx);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
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++)
|
||||
{
|
||||
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)
|
||||
|
@ -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.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()));
|
||||
|
||||
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);
|
||||
|
||||
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)
|
||||
|
@ -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>
|
||||
|
||||
//-------------------------------------------------
|
||||
// font_open - attempt to "open" a handle to the
|
||||
// font with the given name
|
||||
//-------------------------------------------------
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <mmsystem.h>
|
||||
#include <tchar.h>
|
||||
#include <io.h>
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
return global_alloc(osd_font_windows);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
|
@ -507,40 +507,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.
|
||||
|
@ -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
|
||||
|
@ -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 bool open(const char *font_path, const char *name, int &height) = 0;
|
||||
virtual ~osd_font() { }
|
||||
|
||||
/** 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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user