summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2022-07-08 15:38:30 +0300
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2022-07-26 08:38:05 +0300
commit36ef8f29dcea579aab058e1778303e10360c7e83 (patch)
treea8206b91fb0d26e5ec550bcbdaaaf151eb3b80ab /platform
parent3e0e84a54c1c5666c32dbc2abd419b61e071ba33 (diff)
Implement support for loading system fonts on Linux, macOS / iOS and Windows.
Diffstat (limited to 'platform')
-rw-r--r--platform/ios/os_ios.h3
-rw-r--r--platform/ios/os_ios.mm75
-rw-r--r--platform/linuxbsd/detect.py6
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp89
-rw-r--r--platform/linuxbsd/os_linuxbsd.h3
-rw-r--r--platform/macos/os_macos.h2
-rw-r--r--platform/macos/os_macos.mm74
-rw-r--r--platform/windows/detect.py2
-rw-r--r--platform/windows/os_windows.cpp130
-rw-r--r--platform/windows/os_windows.h23
10 files changed, 407 insertions, 0 deletions
diff --git a/platform/ios/os_ios.h b/platform/ios/os_ios.h
index cfd1771653..3b88f53b6a 100644
--- a/platform/ios/os_ios.h
+++ b/platform/ios/os_ios.h
@@ -92,6 +92,9 @@ public:
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
+ virtual Vector<String> get_system_fonts() const override;
+ virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override;
+
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false, String *r_resolved_path = nullptr) override;
virtual Error close_dynamic_library(void *p_library_handle) override;
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false) override;
diff --git a/platform/ios/os_ios.mm b/platform/ios/os_ios.mm
index 880315209e..b9d186f355 100644
--- a/platform/ios/os_ios.mm
+++ b/platform/ios/os_ios.mm
@@ -44,6 +44,7 @@
#import "view_controller.h"
#import <AudioToolbox/AudioServices.h>
+#import <CoreText/CoreText.h>
#import <UIKit/UIKit.h>
#import <dlfcn.h>
#include <sys/sysctl.h>
@@ -302,6 +303,80 @@ String OS_IOS::get_processor_name() const {
ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string."));
}
+Vector<String> OS_IOS::get_system_fonts() const {
+ HashSet<String> font_names;
+ CFArrayRef fonts = CTFontManagerCopyAvailableFontFamilyNames();
+ if (fonts) {
+ for (CFIndex i = 0; i < CFArrayGetCount(fonts); i++) {
+ CFStringRef cf_name = (CFStringRef)CFArrayGetValueAtIndex(fonts, i);
+ if (cf_name && (CFStringGetLength(cf_name) > 0) && (CFStringCompare(cf_name, CFSTR("LastResort"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && (CFStringGetCharacterAtIndex(cf_name, 0) != '.')) {
+ NSString *ns_name = (__bridge NSString *)cf_name;
+ font_names.insert(String::utf8([ns_name UTF8String]));
+ }
+ }
+ CFRelease(fonts);
+ }
+
+ Vector<String> ret;
+ for (const String &E : font_names) {
+ ret.push_back(E);
+ }
+ return ret;
+}
+
+String OS_IOS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const {
+ String ret;
+
+ String font_name = p_font_name;
+ if (font_name.to_lower() == "sans-serif") {
+ font_name = "Helvetica";
+ } else if (font_name.to_lower() == "serif") {
+ font_name = "Times";
+ } else if (font_name.to_lower() == "monospace") {
+ font_name = "Courier";
+ } else if (font_name.to_lower() == "fantasy") {
+ font_name = "Papyrus";
+ } else if (font_name.to_lower() == "cursive") {
+ font_name = "Apple Chancery";
+ };
+
+ CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8);
+
+ CTFontSymbolicTraits traits = 0;
+ if (p_bold) {
+ traits |= kCTFontBoldTrait;
+ }
+ if (p_italic) {
+ traits |= kCTFontItalicTrait;
+ }
+
+ CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits);
+ CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
+ CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits);
+
+ CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
+ CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name);
+ CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict);
+
+ CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes);
+ if (font) {
+ CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(font, kCTFontURLAttribute);
+ if (url) {
+ NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]];
+ ret = String::utf8([font_path UTF8String]);
+ CFRelease(url);
+ }
+ CFRelease(font);
+ }
+
+ CFRelease(attributes);
+ CFRelease(traits_dict);
+ CFRelease(sym_traits);
+ CFRelease(name);
+
+ return ret;
+}
+
void OS_IOS::vibrate_handheld(int p_duration_ms) {
if (ios->supports_haptic_engine()) {
ios->vibrate_haptic_engine((float)p_duration_ms / 1000.f);
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 065250c40e..b9cbf9b97c 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -298,6 +298,12 @@ def configure(env):
## Flags
+ if os.system("pkg-config --exists fontconfig") == 0: # 0 means found
+ env.Append(CPPDEFINES=["FONTCONFIG_ENABLED"])
+ env.ParseConfig("pkg-config fontconfig --cflags --libs")
+ else:
+ print("Warning: fontconfig libraries not found. Disabling the system fonts support.")
+
if os.system("pkg-config --exists alsa") == 0: # 0 means found
env["alsa"] = True
env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"])
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index b73d4dc626..bf4634a4fd 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -52,6 +52,10 @@
#include <sys/types.h>
#include <unistd.h>
+#ifdef FONTCONFIG_ENABLED
+#include <fontconfig/fontconfig.h>
+#endif
+
void OS_LinuxBSD::alert(const String &p_alert, const String &p_title) {
const char *message_programs[] = { "zenity", "kdialog", "Xdialog", "xmessage" };
@@ -327,6 +331,91 @@ uint64_t OS_LinuxBSD::get_embedded_pck_offset() const {
return off;
}
+Vector<String> OS_LinuxBSD::get_system_fonts() const {
+#ifdef FONTCONFIG_ENABLED
+ HashSet<String> font_names;
+ Vector<String> ret;
+
+ FcConfig *config = FcInitLoadConfigAndFonts();
+ ERR_FAIL_COND_V(!config, ret);
+
+ FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, nullptr);
+ ERR_FAIL_COND_V(!object_set, ret);
+
+ static const char *allowed_formats[] = { "TrueType", "CFF" };
+ for (size_t i = 0; i < sizeof(allowed_formats) / sizeof(const char *); i++) {
+ FcPattern *pattern = FcPatternCreate();
+ ERR_CONTINUE(!pattern);
+
+ FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
+ FcPatternAddString(pattern, FC_FONTFORMAT, reinterpret_cast<const FcChar8 *>(allowed_formats[i]));
+
+ FcFontSet *font_set = FcFontList(config, pattern, object_set);
+ if (font_set) {
+ for (int j = 0; j < font_set->nfont; j++) {
+ char *family_name = nullptr;
+ if (FcPatternGetString(font_set->fonts[j], FC_FAMILY, 0, reinterpret_cast<FcChar8 **>(&family_name)) == FcResultMatch) {
+ if (family_name) {
+ font_names.insert(String::utf8(family_name));
+ }
+ }
+ }
+ FcFontSetDestroy(font_set);
+ }
+ FcPatternDestroy(pattern);
+ }
+ FcObjectSetDestroy(object_set);
+
+ for (const String &E : font_names) {
+ ret.push_back(E);
+ }
+ return ret;
+#else
+ ERR_FAIL_COND_V_MSG(Vector<String>(), "Godot was compiled without fontconfig, system font support is disabled.")
+#endif
+}
+
+String OS_LinuxBSD::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const {
+#ifdef FONTCONFIG_ENABLED
+ String ret;
+
+ FcConfig *config = FcInitLoadConfigAndFonts();
+ ERR_FAIL_COND_V(!config, ret);
+
+ FcObjectSet *object_set = FcObjectSetBuild(FC_FAMILY, FC_FILE, nullptr);
+ ERR_FAIL_COND_V(!object_set, ret);
+
+ FcPattern *pattern = FcPatternCreate();
+ if (pattern) {
+ FcPatternAddBool(pattern, FC_SCALABLE, FcTrue);
+ FcPatternAddString(pattern, FC_FAMILY, reinterpret_cast<const FcChar8 *>(p_font_name.utf8().get_data()));
+ FcPatternAddInteger(pattern, FC_WEIGHT, p_bold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL);
+ FcPatternAddInteger(pattern, FC_SLANT, p_italic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN);
+
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ FcDefaultSubstitute(pattern);
+
+ FcResult result;
+ FcPattern *match = FcFontMatch(0, pattern, &result);
+ if (match) {
+ char *file_name = nullptr;
+ if (FcPatternGetString(match, FC_FILE, 0, reinterpret_cast<FcChar8 **>(&file_name)) == FcResultMatch) {
+ if (file_name) {
+ ret = String::utf8(file_name);
+ }
+ }
+
+ FcPatternDestroy(match);
+ }
+ FcPatternDestroy(pattern);
+ }
+ FcObjectSetDestroy(object_set);
+#else
+ ERR_FAIL_COND_V_MSG(Vector<String>(), "Godot was compiled without fontconfig, system font support is disabled.")
+#endif
+ return ret;
+}
+
String OS_LinuxBSD::get_config_path() const {
if (has_environment("XDG_CONFIG_HOME")) {
if (get_environment("XDG_CONFIG_HOME").is_absolute_path()) {
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
index 13c07842fb..095bcb6427 100644
--- a/platform/linuxbsd/os_linuxbsd.h
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -80,6 +80,9 @@ public:
virtual uint64_t get_embedded_pck_offset() const override;
+ virtual Vector<String> get_system_fonts() const override;
+ virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override;
+
virtual String get_config_path() const override;
virtual String get_data_path() const override;
virtual String get_cache_path() const override;
diff --git a/platform/macos/os_macos.h b/platform/macos/os_macos.h
index a6c23ab71e..a1eb0f7f69 100644
--- a/platform/macos/os_macos.h
+++ b/platform/macos/os_macos.h
@@ -97,6 +97,8 @@ public:
virtual String get_locale() const override;
+ virtual Vector<String> get_system_fonts() const override;
+ virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override;
virtual String get_executable_path() const override;
virtual Error create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id = nullptr, bool p_open_console = false) override;
virtual Error create_instance(const List<String> &p_arguments, ProcessID *r_child_id = nullptr) override;
diff --git a/platform/macos/os_macos.mm b/platform/macos/os_macos.mm
index 2c6cd7de0b..cc550043de 100644
--- a/platform/macos/os_macos.mm
+++ b/platform/macos/os_macos.mm
@@ -303,6 +303,80 @@ String OS_MacOS::get_locale() const {
return String([locale_code UTF8String]).replace("-", "_");
}
+Vector<String> OS_MacOS::get_system_fonts() const {
+ HashSet<String> font_names;
+ CFArrayRef fonts = CTFontManagerCopyAvailableFontFamilyNames();
+ if (fonts) {
+ for (CFIndex i = 0; i < CFArrayGetCount(fonts); i++) {
+ CFStringRef cf_name = (CFStringRef)CFArrayGetValueAtIndex(fonts, i);
+ if (cf_name && (CFStringGetLength(cf_name) > 0) && (CFStringCompare(cf_name, CFSTR("LastResort"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && (CFStringGetCharacterAtIndex(cf_name, 0) != '.')) {
+ NSString *ns_name = (__bridge NSString *)cf_name;
+ font_names.insert(String::utf8([ns_name UTF8String]));
+ }
+ }
+ CFRelease(fonts);
+ }
+
+ Vector<String> ret;
+ for (const String &E : font_names) {
+ ret.push_back(E);
+ }
+ return ret;
+}
+
+String OS_MacOS::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const {
+ String ret;
+
+ String font_name = p_font_name;
+ if (font_name.to_lower() == "sans-serif") {
+ font_name = "Helvetica";
+ } else if (font_name.to_lower() == "serif") {
+ font_name = "Times";
+ } else if (font_name.to_lower() == "monospace") {
+ font_name = "Courier";
+ } else if (font_name.to_lower() == "fantasy") {
+ font_name = "Papyrus";
+ } else if (font_name.to_lower() == "cursive") {
+ font_name = "Apple Chancery";
+ };
+
+ CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8);
+
+ CTFontSymbolicTraits traits = 0;
+ if (p_bold) {
+ traits |= kCTFontBoldTrait;
+ }
+ if (p_italic) {
+ traits |= kCTFontItalicTrait;
+ }
+
+ CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits);
+ CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
+ CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits);
+
+ CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
+ CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name);
+ CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict);
+
+ CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes);
+ if (font) {
+ CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(font, kCTFontURLAttribute);
+ if (url) {
+ NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]];
+ ret = String::utf8([font_path UTF8String]);
+ CFRelease(url);
+ }
+ CFRelease(font);
+ }
+
+ CFRelease(attributes);
+ CFRelease(traits_dict);
+ CFRelease(sym_traits);
+ CFRelease(name);
+
+ return ret;
+}
+
String OS_MacOS::get_executable_path() const {
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
int pid = getpid();
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 6a7caf4656..dd2df1f004 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -270,6 +270,7 @@ def configure_msvc(env, manual_msvc_config):
"bcrypt",
"Avrt",
"dwmapi",
+ "dwrite",
]
if env["vulkan"]:
@@ -441,6 +442,7 @@ def configure_mingw(env):
"avrt",
"uuid",
"dwmapi",
+ "dwrite",
]
)
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index b5423e62bf..ad4be950cc 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -48,6 +48,7 @@
#include <avrt.h>
#include <bcrypt.h>
#include <direct.h>
+#include <dwrite.h>
#include <knownfolders.h>
#include <process.h>
#include <regstr.h>
@@ -621,6 +622,135 @@ Error OS_Windows::set_cwd(const String &p_cwd) {
return OK;
}
+Vector<String> OS_Windows::get_system_fonts() const {
+ Vector<String> ret;
+ HashSet<String> font_names;
+
+ ComAutoreleaseRef<IDWriteFactory> dwrite_factory;
+ HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory.reference));
+ ERR_FAIL_COND_V(FAILED(hr) || dwrite_factory.is_null(), ret);
+
+ ComAutoreleaseRef<IDWriteFontCollection> font_collection;
+ hr = dwrite_factory->GetSystemFontCollection(&font_collection.reference, false);
+ ERR_FAIL_COND_V(FAILED(hr) || font_collection.is_null(), ret);
+
+ UINT32 family_count = font_collection->GetFontFamilyCount();
+ for (UINT32 i = 0; i < family_count; i++) {
+ ComAutoreleaseRef<IDWriteFontFamily> family;
+ hr = font_collection->GetFontFamily(i, &family.reference);
+ ERR_CONTINUE(FAILED(hr) || family.is_null());
+
+ ComAutoreleaseRef<IDWriteLocalizedStrings> family_names;
+ hr = family->GetFamilyNames(&family_names.reference);
+ ERR_CONTINUE(FAILED(hr) || family_names.is_null());
+
+ UINT32 index = 0;
+ BOOL exists = false;
+ UINT32 length = 0;
+ Char16String name;
+
+ hr = family_names->FindLocaleName(L"en-us", &index, &exists);
+ ERR_CONTINUE(FAILED(hr));
+
+ hr = family_names->GetStringLength(index, &length);
+ ERR_CONTINUE(FAILED(hr));
+
+ name.resize(length + 1);
+ hr = family_names->GetString(index, (WCHAR *)name.ptrw(), length + 1);
+ ERR_CONTINUE(FAILED(hr));
+
+ font_names.insert(String::utf16(name.ptr(), length));
+ }
+
+ for (const String &E : font_names) {
+ ret.push_back(E);
+ }
+ return ret;
+}
+
+String OS_Windows::get_system_font_path(const String &p_font_name, bool p_bold, bool p_italic) const {
+ String font_name = p_font_name;
+ if (font_name.to_lower() == "sans-serif") {
+ font_name = "Arial";
+ } else if (font_name.to_lower() == "serif") {
+ font_name = "Times New Roman";
+ } else if (font_name.to_lower() == "monospace") {
+ font_name = "Courier New";
+ } else if (font_name.to_lower() == "cursive") {
+ font_name = "Comic Sans MS";
+ } else if (font_name.to_lower() == "fantasy") {
+ font_name = "Gabriola";
+ }
+
+ ComAutoreleaseRef<IDWriteFactory> dwrite_factory;
+ HRESULT hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown **>(&dwrite_factory.reference));
+ ERR_FAIL_COND_V(FAILED(hr) || dwrite_factory.is_null(), String());
+
+ ComAutoreleaseRef<IDWriteFontCollection> font_collection;
+ hr = dwrite_factory->GetSystemFontCollection(&font_collection.reference, false);
+ ERR_FAIL_COND_V(FAILED(hr) || font_collection.is_null(), String());
+
+ UINT32 index = 0;
+ BOOL exists = false;
+ font_collection->FindFamilyName((const WCHAR *)font_name.utf16().get_data(), &index, &exists);
+ if (FAILED(hr)) {
+ return String();
+ }
+
+ ComAutoreleaseRef<IDWriteFontFamily> family;
+ hr = font_collection->GetFontFamily(index, &family.reference);
+ if (FAILED(hr) || family.is_null()) {
+ return String();
+ }
+
+ ComAutoreleaseRef<IDWriteFont> dwrite_font;
+ hr = family->GetFirstMatchingFont(p_bold ? DWRITE_FONT_WEIGHT_BOLD : DWRITE_FONT_WEIGHT_NORMAL, DWRITE_FONT_STRETCH_NORMAL, p_italic ? DWRITE_FONT_STYLE_ITALIC : DWRITE_FONT_STYLE_NORMAL, &dwrite_font.reference);
+ if (FAILED(hr) || dwrite_font.is_null()) {
+ return String();
+ }
+
+ ComAutoreleaseRef<IDWriteFontFace> dwrite_face;
+ hr = dwrite_font->CreateFontFace(&dwrite_face.reference);
+ if (FAILED(hr) || dwrite_face.is_null()) {
+ return String();
+ }
+
+ UINT32 number_of_files = 0;
+ hr = dwrite_face->GetFiles(&number_of_files, nullptr);
+ if (FAILED(hr)) {
+ return String();
+ }
+ Vector<ComAutoreleaseRef<IDWriteFontFile>> files;
+ files.resize(number_of_files);
+ hr = dwrite_face->GetFiles(&number_of_files, (IDWriteFontFile **)files.ptrw());
+ if (FAILED(hr)) {
+ return String();
+ }
+
+ for (UINT32 i = 0; i < number_of_files; i++) {
+ void const *reference_key = nullptr;
+ UINT32 reference_key_size = 0;
+ ComAutoreleaseRef<IDWriteLocalFontFileLoader> loader;
+
+ hr = files.write[i]->GetLoader((IDWriteFontFileLoader **)&loader.reference);
+ if (FAILED(hr) || loader.is_null()) {
+ continue;
+ }
+ hr = files.write[i]->GetReferenceKey(&reference_key, &reference_key_size);
+ if (FAILED(hr)) {
+ continue;
+ }
+
+ WCHAR file_path[MAX_PATH];
+ hr = loader->GetFilePathFromKey(reference_key, reference_key_size, &file_path[0], MAX_PATH);
+ if (FAILED(hr)) {
+ continue;
+ }
+ return String::utf16((const char16_t *)&file_path[0]);
+ }
+ return String();
+}
+
String OS_Windows::get_executable_path() const {
WCHAR bufname[4096];
GetModuleFileNameW(nullptr, bufname, 4096);
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 7d2d4ae705..80fc860738 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -62,6 +62,26 @@
#define WINDOWS_DEBUG_OUTPUT_ENABLED
#endif
+template <class T>
+class ComAutoreleaseRef {
+public:
+ T *reference = nullptr;
+
+ _FORCE_INLINE_ T *operator->() { return reference; }
+ _FORCE_INLINE_ const T *operator->() const { return reference; }
+ _FORCE_INLINE_ T *operator*() { return reference; }
+ _FORCE_INLINE_ const T *operator*() const { return reference; }
+ _FORCE_INLINE_ bool is_valid() const { return reference != nullptr; }
+ _FORCE_INLINE_ bool is_null() const { return reference == nullptr; }
+ ComAutoreleaseRef() {}
+ ~ComAutoreleaseRef() {
+ if (reference != nullptr) {
+ reference->Release();
+ reference = nullptr;
+ }
+ }
+};
+
class JoypadWindows;
class OS_Windows : public OS {
#ifdef STDOUT_FILE
@@ -147,6 +167,9 @@ public:
virtual String get_environment(const String &p_var) const override;
virtual bool set_environment(const String &p_var, const String &p_value) const override;
+ virtual Vector<String> get_system_fonts() const override;
+ virtual String get_system_font_path(const String &p_font_name, bool p_bold = false, bool p_italic = false) const override;
+
virtual String get_executable_path() const override;
virtual String get_locale() const override;