mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 22:28:24 +02:00
Compile the core_text module using Objective-C
This commit is contained in:
@@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* core_text.c
|
|
||||||
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
|
|
||||||
*
|
|
||||||
* Distributed under terms of the GPL3 license.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "data-types.h"
|
|
||||||
#include <structmember.h>
|
|
||||||
#include <CoreText/CTFont.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PyObject_HEAD
|
|
||||||
|
|
||||||
unsigned int units_per_EM;
|
|
||||||
int ascender, descender, height, max_advance_width, max_advance_height, underline_position, underline_thickness;
|
|
||||||
} Face;
|
|
||||||
|
|
||||||
|
|
||||||
static PyObject*
|
|
||||||
new(PyTypeObject *type, PyObject UNUSED *args, PyObject UNUSED *kwds) {
|
|
||||||
Face *self;
|
|
||||||
self = (Face *)type->tp_alloc(type, 0);
|
|
||||||
return (PyObject*)self;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
dealloc(Face* self) {
|
|
||||||
Py_TYPE(self)->tp_free((PyObject*)self);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Boilerplate {{{
|
|
||||||
|
|
||||||
static PyMemberDef members[] = {
|
|
||||||
#define MEM(name, type) {#name, type, offsetof(Face, name), READONLY, #name}
|
|
||||||
MEM(units_per_EM, T_UINT),
|
|
||||||
MEM(ascender, T_INT),
|
|
||||||
MEM(descender, T_INT),
|
|
||||||
MEM(height, T_INT),
|
|
||||||
MEM(max_advance_width, T_INT),
|
|
||||||
MEM(max_advance_height, T_INT),
|
|
||||||
MEM(underline_position, T_INT),
|
|
||||||
MEM(underline_thickness, T_INT),
|
|
||||||
{NULL} /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
static PyMethodDef methods[] = {
|
|
||||||
{NULL} /* Sentinel */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
PyTypeObject Face_Type = {
|
|
||||||
PyVarObject_HEAD_INIT(NULL, 0)
|
|
||||||
.tp_name = "fast_data_types.CTFace",
|
|
||||||
.tp_basicsize = sizeof(Face),
|
|
||||||
.tp_dealloc = (destructor)dealloc,
|
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT,
|
|
||||||
.tp_doc = "CoreText Font face",
|
|
||||||
.tp_methods = methods,
|
|
||||||
.tp_members = members,
|
|
||||||
.tp_new = new,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
init_CoreText(PyObject *module) {
|
|
||||||
if (PyType_Ready(&Face_Type) < 0) return 0;
|
|
||||||
if (PyModule_AddObject(module, "CTFace", (PyObject *)&Face_Type) != 0) return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
106
kitty/core_text.m
Normal file
106
kitty/core_text.m
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* core_text.c
|
||||||
|
* Copyright (C) 2017 Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the GPL3 license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "data-types.h"
|
||||||
|
#include <structmember.h>
|
||||||
|
#import <CoreText/CTFont.h>
|
||||||
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
|
||||||
|
unsigned int units_per_em;
|
||||||
|
float ascent, descent, leading, underline_position, underline_thickness;
|
||||||
|
CTFontRef font;
|
||||||
|
} Face;
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
new(PyTypeObject *type, PyObject *args, PyObject UNUSED *kwds) {
|
||||||
|
Face *self;
|
||||||
|
int bold, italic;
|
||||||
|
char *cfamily;
|
||||||
|
float point_sz;
|
||||||
|
if(!PyArg_ParseTuple(args, "sppf", &cfamily, &bold, &italic, &point_sz)) return NULL;
|
||||||
|
NSString *family = [[NSString alloc] initWithCString:cfamily encoding:NSUTF8StringEncoding];
|
||||||
|
if (family == NULL) return PyErr_NoMemory();
|
||||||
|
self = (Face *)type->tp_alloc(type, 0);
|
||||||
|
if (self) {
|
||||||
|
CTFontSymbolicTraits symbolic_traits = (bold ? kCTFontBoldTrait : 0) | (italic ? kCTFontItalicTrait : 0);
|
||||||
|
NSDictionary *font_traits = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:symbolic_traits] forKey:(NSString *)kCTFontSymbolicTrait];
|
||||||
|
NSDictionary *font_attributes = [NSDictionary dictionaryWithObjectsAndKeys:family, kCTFontFamilyNameAttribute, font_traits, kCTFontTraitsAttribute, nil];
|
||||||
|
CTFontDescriptorRef descriptor = CTFontDescriptorCreateWithAttributes((CFDictionaryRef)font_attributes);
|
||||||
|
if (descriptor) {
|
||||||
|
self->font = CTFontCreateWithFontDescriptor(descriptor, point_sz, NULL);
|
||||||
|
CFRelease(descriptor);
|
||||||
|
if (!self->font) { Py_CLEAR(self); PyErr_SetString(PyExc_ValueError, "Failed to create CTFont object"); }
|
||||||
|
else {
|
||||||
|
self->units_per_em = CTFontGetUnitsPerEm(self->font);
|
||||||
|
self->ascent = CTFontGetAscent(self->font);
|
||||||
|
self->descent = CTFontGetDescent(self->font);
|
||||||
|
self->leading = CTFontGetLeading(self->font);
|
||||||
|
self->underline_position = CTFontGetUnderlinePosition(self->font);
|
||||||
|
self->underline_thickness = CTFontGetUnderlineThickness(self->font);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Py_CLEAR(self);
|
||||||
|
PyErr_NoMemory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[ family release ];
|
||||||
|
return (PyObject*)self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
dealloc(Face* self) {
|
||||||
|
if (self->font) CFRelease(self->font);
|
||||||
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Boilerplate {{{
|
||||||
|
|
||||||
|
static PyMemberDef members[] = {
|
||||||
|
#define MEM(name, type) {#name, type, offsetof(Face, name), READONLY, #name}
|
||||||
|
MEM(units_per_em, T_UINT),
|
||||||
|
MEM(ascent, T_FLOAT),
|
||||||
|
MEM(descent, T_FLOAT),
|
||||||
|
MEM(leading, T_FLOAT),
|
||||||
|
MEM(underline_position, T_FLOAT),
|
||||||
|
MEM(underline_thickness, T_FLOAT),
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyMethodDef methods[] = {
|
||||||
|
{NULL} /* Sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
PyTypeObject Face_Type = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
.tp_name = "fast_data_types.CTFace",
|
||||||
|
.tp_basicsize = sizeof(Face),
|
||||||
|
.tp_dealloc = (destructor)dealloc,
|
||||||
|
.tp_flags = Py_TPFLAGS_DEFAULT,
|
||||||
|
.tp_doc = "CoreText Font face",
|
||||||
|
.tp_methods = methods,
|
||||||
|
.tp_members = members,
|
||||||
|
.tp_new = new,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
init_CoreText(PyObject *module) {
|
||||||
|
if (PyType_Ready(&Face_Type) < 0) return 0;
|
||||||
|
if (PyModule_AddObject(module, "CTFace", (PyObject *)&Face_Type) != 0) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// }}}
|
||||||
4
setup.py
4
setup.py
@@ -169,9 +169,9 @@ def option_parser():
|
|||||||
def find_c_files():
|
def find_c_files():
|
||||||
ans = []
|
ans = []
|
||||||
d = os.path.join(base, 'kitty')
|
d = os.path.join(base, 'kitty')
|
||||||
exclude = {'freetype.c'} if isosx else {'core_text.c'}
|
exclude = {'freetype.c'} if isosx else {'core_text.m'}
|
||||||
for x in os.listdir(d):
|
for x in os.listdir(d):
|
||||||
if x.endswith('.c') and os.path.basename(x) not in exclude:
|
if (x.endswith('.c') or x.endswith('.m')) and os.path.basename(x) not in exclude:
|
||||||
ans.append(os.path.join('kitty', x))
|
ans.append(os.path.join('kitty', x))
|
||||||
ans.sort(key=lambda x: os.path.getmtime(os.path.join(base, x)), reverse=True)
|
ans.sort(key=lambda x: os.path.getmtime(os.path.join(base, x)), reverse=True)
|
||||||
ans.append('kitty/parser_dump.c')
|
ans.append('kitty/parser_dump.c')
|
||||||
|
|||||||
Reference in New Issue
Block a user