diff --git a/kitty/core_text.h b/kitty/core_text.h new file mode 100644 index 000000000..83fd1bf11 --- /dev/null +++ b/kitty/core_text.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2017 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#pragma once + +#define UNUSED __attribute__ ((unused)) + +int init_CoreText(PyObject *); +PyObject* coretext_all_fonts(PyObject UNUSED *self); + +#define CORE_TEXT_FUNC_WRAPPERS \ + {"coretext_all_fonts", (PyCFunction)coretext_all_fonts, METH_NOARGS, ""}, diff --git a/kitty/core_text.m b/kitty/core_text.m index 53235ca56..85148eba6 100644 --- a/kitty/core_text.m +++ b/kitty/core_text.m @@ -11,6 +11,8 @@ #include #import #import +#include +#include #import #import @@ -28,11 +30,61 @@ static PyObject* convert_cfstring(CFStringRef src) { #define SZ 2048 static char buf[SZ+2] = {0}; + const char *p = CFStringGetCStringPtr(src, kCFStringEncodingUTF8); + if (p != NULL) return PyUnicode_FromString(buf); if(!CFStringGetCString(src, buf, SZ, kCFStringEncodingUTF8)) { PyErr_SetString(PyExc_ValueError, "Failed to convert CFString"); return NULL; } return PyUnicode_FromString(buf); #undef SZ } +static PyObject* +font_descriptor_to_python(CTFontDescriptorRef descriptor) { + NSURL *url = (NSURL *) CTFontDescriptorCopyAttribute(descriptor, kCTFontURLAttribute); + NSString *psName = (NSString *) CTFontDescriptorCopyAttribute(descriptor, kCTFontNameAttribute); + NSString *family = (NSString *) CTFontDescriptorCopyAttribute(descriptor, kCTFontFamilyNameAttribute); + NSString *style = (NSString *) CTFontDescriptorCopyAttribute(descriptor, kCTFontStyleNameAttribute); + NSDictionary *traits = (NSDictionary *) CTFontDescriptorCopyAttribute(descriptor, kCTFontTraitsAttribute); + unsigned int straits = [traits[(id)kCTFontSymbolicTrait] unsignedIntValue]; + NSNumber *weightVal = traits[(id)kCTFontWeightTrait]; + NSNumber *widthVal = traits[(id)kCTFontWidthTrait]; + + PyObject *ans = Py_BuildValue("{ssssssss sOsOsO sfsfsI}", + "path", [[url path] UTF8String], + "postscript_name", [psName UTF8String], + "family", [family UTF8String], + "style", [style UTF8String], + + "bold", (straits & kCTFontBoldTrait) != 0 ? Py_True : Py_False, + "italic", (straits & kCTFontItalicTrait) != 0 ? Py_True : Py_False, + "monospace", (straits & kCTFontMonoSpaceTrait) != 0 ? Py_True : Py_False, + + "weight", [weightVal floatValue], + "width", [widthVal floatValue], + "traits", straits + ); + [url release]; + [psName release]; + [family release]; + [style release]; + [traits release]; + return ans; +} + +PyObject* +coretext_all_fonts(PyObject UNUSED *_self) { + static CTFontCollectionRef collection = NULL; + if (collection == NULL) collection = CTFontCollectionCreateFromAvailableFonts(NULL); + NSArray *matches = (NSArray *) CTFontCollectionCreateMatchingFontDescriptors(collection); + PyObject *ans = PyTuple_New([matches count]), *temp; + if (ans == NULL) return PyErr_NoMemory(); + for (unsigned int i = 0; i < [matches count]; i++) { + temp = font_descriptor_to_python((CTFontDescriptorRef) matches[i]); + if (temp == NULL) { Py_DECREF(ans); return NULL; } + PyTuple_SET_ITEM(ans, i, temp); temp = NULL; + } + return ans; +} + static PyObject* new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) { diff --git a/kitty/data-types.c b/kitty/data-types.c index 0202dbda7..82f18916c 100644 --- a/kitty/data-types.c +++ b/kitty/data-types.c @@ -41,6 +41,9 @@ redirect_std_streams(PyObject UNUSED *self, PyObject *args) { Py_RETURN_NONE; } +#ifdef __APPLE__ +#include "core_text.h" +#endif static PyMethodDef module_methods[] = { GL_METHODS @@ -52,7 +55,9 @@ static PyMethodDef module_methods[] = { {"redirect_std_streams", (PyCFunction)redirect_std_streams, METH_VARARGS, ""}, {"wcwidth", (PyCFunction)wcwidth_wrap, METH_O, ""}, {"change_wcwidth", (PyCFunction)change_wcwidth_wrap, METH_O, ""}, -#ifndef __APPLE__ +#ifdef __APPLE__ + CORE_TEXT_FUNC_WRAPPERS +#else {"get_fontconfig_font", (PyCFunction)get_fontconfig_font, METH_VARARGS, ""}, #endif GLFW_FUNC_WRAPPERS diff --git a/kitty/data-types.h b/kitty/data-types.h index f05bee15f..69e6ff5a3 100644 --- a/kitty/data-types.h +++ b/kitty/data-types.h @@ -319,7 +319,6 @@ int init_ChangeTracker(PyObject *); int init_Screen(PyObject *); int init_Face(PyObject *); int init_Window(PyObject *); -int init_CoreText(PyObject *); PyObject* create_256_color_table(); PyObject* read_bytes_dump(PyObject UNUSED *, PyObject *); PyObject* read_bytes(PyObject UNUSED *, PyObject *);