summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/modules/font/font_osx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/modules/font/font_osx.cpp')
-rw-r--r--src/osd/modules/font/font_osx.cpp139
1 files changed, 110 insertions, 29 deletions
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)