summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/font/font_windows.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2016-03-16 19:42:01 +1100
committer Vas Crabb <vas@vastheman.com>2016-03-17 00:04:52 +1100
commita3b35f8bc689901ac82a2d47bbe344a57c3632ba (patch)
tree0ffb561e756b9b46e1021dff80a16a410eab61a7 /src/osd/modules/font/font_windows.cpp
parent7b7f2a3fb02c4515392b307ea04bb968450bdbbf (diff)
Move font enumeration to OSD, separate font name from display name as needed for OSX
Diffstat (limited to 'src/osd/modules/font/font_windows.cpp')
-rw-r--r--src/osd/modules/font/font_windows.cpp116
1 files changed, 84 insertions, 32 deletions
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)