def supports_text(self, text, has_non_printable_chars=True): ''' Returns True if all the characters in text have glyphs in this font. ''' if not isinstance(text, unicode): raise TypeError('%r is not a unicode object'%text) if has_non_printable_chars: from calibre.utils.fonts.utils import get_printable_characters text = get_printable_characters(text) chars = tuple(frozenset(map(ord, text))) return self.face.supports_text(chars)
def find_font_for_text(self, text, allowed_families={'serif', 'sans-serif'}, preferred_families=('serif', 'sans-serif', 'monospace', 'cursive', 'fantasy')): ''' Find a font on the system capable of rendering the given text. Returns a font family (as given by fonts_for_family()) that has a "normal" font and that can render the supplied text. If no such font exists, returns None. :return: (family name, faces) or None, None ''' from calibre.utils.fonts.utils import (supports_text, panose_to_css_generic_family, get_printable_characters) if not isinstance(text, unicode_type): raise TypeError(u'%r is not unicode' % text) text = get_printable_characters(text) found = {} def filter_faces(font): try: raw = self.get_font_data(font) return supports_text(raw, text) except: pass return False for family in self.find_font_families(): faces = list(filter(filter_faces, self.fonts_for_family(family))) if not faces: continue generic_family = panose_to_css_generic_family(faces[0]['panose']) if generic_family in allowed_families or generic_family == preferred_families[ 0]: return (family, faces) elif generic_family not in found: found[generic_family] = (family, faces) for f in preferred_families: if f in found: return found[f] return None, None
def find_font_for_text( self, text, allowed_families={"serif", "sans-serif"}, preferred_families=("serif", "sans-serif", "monospace", "cursive", "fantasy"), ): """ Find a font on the system capable of rendering the given text. Returns a font family (as given by fonts_for_family()) that has a "normal" font and that can render the supplied text. If no such font exists, returns None. :return: (family name, faces) or None, None """ from calibre.utils.fonts.utils import supports_text, panose_to_css_generic_family, get_printable_characters if not isinstance(text, unicode): raise TypeError("%r is not unicode" % text) text = get_printable_characters(text) found = {} def filter_faces(font): try: raw = self.get_font_data(font) return supports_text(raw, text) except: pass return False for family in self.find_font_families(): faces = filter(filter_faces, self.fonts_for_family(family)) if not faces: continue generic_family = panose_to_css_generic_family(faces[0]["panose"]) if generic_family in allowed_families or generic_family == preferred_families[0]: return (family, faces) elif generic_family not in found: found[generic_family] = (family, faces) for f in preferred_families: if f in found: return found[f] return None, None