CoreText: Use a scoring function to find the best matching font

Also if the specified family does not exist, fallback to Menlo
This commit is contained in:
Kovid Goyal 2017-08-25 09:53:11 +05:30
parent 212207d667
commit fa8203ff31
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -29,18 +29,27 @@ def create_font_map(all_fonts):
def find_best_match(font_map, family, bold, italic): def find_best_match(font_map, family, bold, italic):
q = re.sub(r'\s+', ' ', family.lower()) q = re.sub(r'\s+', ' ', family.lower())
def matches(candidate, monospace): def score(candidate):
return candidate['bold'] == bold and candidate['italic'] == italic and candidate['monospace'] == monospace style_match = 1 if candidate['bold'] == bold and candidate['italic'] == italic else 0
monospace_match = 1 if candidate['monospace'] else 0
return style_match, monospace_match
for monospace in (True, False): # First look for an exact match
for selector in 'ps_map full_map family_map'.split(): for selector in ('ps_map', 'full_map'):
candidates = font_map[selector].get(q, ()) candidates = font_map[selector].get(q)
if candidates: if candidates:
for candidate in candidates: candidates.sort(key=score)
if matches(candidate, monospace): return candidates[-1]
return candidate
if selector != 'family_map': # Let CoreText choose the font if the family exists, otherwise
return candidates[0] # fallback to Menlo
family = family if q in font_map['family_map'] else 'Menlo'
return {
'monospace': True,
'bold': bold,
'italic': italic,
'family': family
}
def get_face(font_map, family, main_family, font_size, dpi, bold=False, italic=False): def get_face(font_map, family, main_family, font_size, dpi, bold=False, italic=False):
@ -51,12 +60,7 @@ def get_face(font_map, family, main_family, font_size, dpi, bold=False, italic=F
f = main_family f = main_family
return f return f
family = resolve_family(family) family = resolve_family(family)
descriptor = find_best_match(font_map, family, bold, italic) or { descriptor = find_best_match(font_map, family, bold, italic)
'monospace': True,
'bold': bold,
'italic': italic,
'family': family
}
return Face(descriptor, font_size, dpi) return Face(descriptor, font_size, dpi)