mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 22:28:24 +02:00
Make CoreText signatures for some font finding methods the same as their equivalents in fontconfig
This commit is contained in:
@@ -137,7 +137,7 @@ font_descriptor_to_python(CTFontDescriptorRef descriptor) {
|
||||
|
||||
"bold", (symbolic_traits & kCTFontBoldTrait) != 0 ? Py_True : Py_False,
|
||||
"italic", (symbolic_traits & kCTFontItalicTrait) != 0 ? Py_True : Py_False,
|
||||
"monospace", (symbolic_traits & kCTFontMonoSpaceTrait) != 0 ? Py_True : Py_False,
|
||||
"monospace", (symbolic_traits & kCTFontTraitMonoSpace) != 0 ? Py_True : Py_False,
|
||||
"expanded", (symbolic_traits & kCTFontExpandedTrait) != 0 ? Py_True : Py_False,
|
||||
"condensed", (symbolic_traits & kCTFontCondensedTrait) != 0 ? Py_True : Py_False,
|
||||
"color_glyphs", (symbolic_traits & kCTFontColorGlyphsTrait) != 0 ? Py_True : Py_False,
|
||||
@@ -185,17 +185,33 @@ all_fonts_collection(void) {
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
coretext_all_fonts(PyObject UNUSED *_self) {
|
||||
CFArrayRef matches = CTFontCollectionCreateMatchingFontDescriptors(all_fonts_collection());
|
||||
coretext_all_fonts(PyObject UNUSED *_self, PyObject *monospaced_only_) {
|
||||
int monospaced_only = PyObject_IsTrue(monospaced_only_);
|
||||
RAII_CoreFoundation(CFArrayRef, matches, CTFontCollectionCreateMatchingFontDescriptors(all_fonts_collection()));
|
||||
const CFIndex count = CFArrayGetCount(matches);
|
||||
PyObject *ans = PyTuple_New(count), *temp;
|
||||
if (ans == NULL) { CFRelease(matches); return PyErr_NoMemory(); }
|
||||
RAII_PyObject(ans, PyTuple_New(count));
|
||||
if (ans == NULL) return NULL;
|
||||
PyObject *temp;
|
||||
Py_ssize_t num = 0;
|
||||
for (CFIndex i = 0; i < count; i++) {
|
||||
temp = font_descriptor_to_python((CTFontDescriptorRef) CFArrayGetValueAtIndex(matches, i));
|
||||
if (temp == NULL) { CFRelease(matches); Py_DECREF(ans); return NULL; }
|
||||
PyTuple_SET_ITEM(ans, i, temp); temp = NULL;
|
||||
CTFontDescriptorRef desc = (CTFontDescriptorRef) CFArrayGetValueAtIndex(matches, i);
|
||||
if (monospaced_only) {
|
||||
RAII_CoreFoundation(CFDictionaryRef, traits, CTFontDescriptorCopyAttribute(desc, kCTFontTraitsAttribute));
|
||||
if (traits) {
|
||||
unsigned long symbolic_traits;
|
||||
CFNumberRef value = (CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait);
|
||||
if (value) {
|
||||
CFNumberGetValue(value, kCFNumberLongType, &symbolic_traits);
|
||||
if (!(symbolic_traits & kCTFontTraitMonoSpace)) continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
temp = font_descriptor_to_python(desc);
|
||||
if (temp == NULL) return NULL;
|
||||
PyTuple_SET_ITEM(ans, num++, temp); temp = NULL;
|
||||
}
|
||||
CFRelease(matches);
|
||||
if (_PyTuple_Resize(&ans, num) == -1) return NULL;
|
||||
Py_INCREF(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
@@ -855,7 +871,7 @@ repr(CTFace *self) {
|
||||
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
METHODB(coretext_all_fonts, METH_NOARGS),
|
||||
METHODB(coretext_all_fonts, METH_O),
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
@@ -455,7 +455,7 @@ class CTFace:
|
||||
def display_name(self) -> str: ...
|
||||
|
||||
|
||||
def coretext_all_fonts() -> Tuple[CoreTextFont, ...]:
|
||||
def coretext_all_fonts(monospaced_only: bool) -> Tuple[CoreTextFont, ...]:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import re
|
||||
from functools import lru_cache
|
||||
from typing import Dict, Generator, Iterable, List, Optional, Tuple
|
||||
|
||||
from kitty.fast_data_types import coretext_all_fonts
|
||||
@@ -33,16 +34,13 @@ def create_font_map(all_fonts: Iterable[CoreTextFont]) -> FontMap:
|
||||
return ans
|
||||
|
||||
|
||||
def all_fonts_map() -> FontMap:
|
||||
ans: Optional[FontMap] = getattr(all_fonts_map, 'ans', None)
|
||||
if ans is None:
|
||||
ans = create_font_map(coretext_all_fonts())
|
||||
setattr(all_fonts_map, 'ans', ans)
|
||||
return ans
|
||||
@lru_cache(maxsize=2)
|
||||
def all_fonts_map(monospaced: bool = True) -> FontMap:
|
||||
return create_font_map(coretext_all_fonts(monospaced))
|
||||
|
||||
|
||||
def list_fonts() -> Generator[ListedFont, None, None]:
|
||||
for fd in coretext_all_fonts():
|
||||
for fd in coretext_all_fonts(False):
|
||||
f = fd['family']
|
||||
if f:
|
||||
fn = fd['display_name']
|
||||
@@ -52,9 +50,11 @@ def list_fonts() -> Generator[ListedFont, None, None]:
|
||||
'is_variable': fd['variable'], 'descriptor': fd}
|
||||
|
||||
|
||||
def find_best_match(family: str, bold: bool = False, italic: bool = False, ignore_face: Optional[CoreTextFont] = None) -> CoreTextFont:
|
||||
def find_best_match(
|
||||
family: str, bold: bool = False, italic: bool = False, monospaced: bool = True, ignore_face: Optional[CoreTextFont] = None
|
||||
) -> CoreTextFont:
|
||||
q = re.sub(r'\s+', ' ', family.lower())
|
||||
font_map = all_fonts_map()
|
||||
font_map = all_fonts_map(monospaced)
|
||||
|
||||
def score(candidate: CoreTextFont) -> Tuple[int, int, int, float]:
|
||||
style_match = 1 if candidate['bold'] == bold and candidate[
|
||||
@@ -115,7 +115,7 @@ def get_font_files(opts: Options) -> Dict[str, CoreTextFont]:
|
||||
|
||||
|
||||
def font_for_family(family: str) -> Tuple[CoreTextFont, bool, bool]:
|
||||
ans = find_best_match(family)
|
||||
ans = find_best_match(family, monospaced=False)
|
||||
return ans, ans['bold'], ans['italic']
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user