def get_font_files(opts): ans = {} attr_map = { 'bold': 'bold_font', 'italic': 'italic_font', 'bi': 'bold_italic_font' } def get_family(key=None): ans = getattr(opts, attr_map.get(key, 'font_family')) if ans == 'auto' and key: ans = get_family() return ans n = get_font_information(get_family()) ans['regular'] = n._replace(face=Face(n.face, n.index)) def do(key): b = get_font_information( get_family(key), bold=key in ('bold', 'bi'), italic=key in ('italic', 'bi') ) if b.face != n.face: ans[key] = b._replace(face=Face(b.face, b.index)) do('bold'), do('italic'), do('bi') return ans
def render_char(text, bold=False, italic=False, width=1): key = 'regular' if bold: key = 'bi' if italic else 'bold' elif italic: key = 'italic' ch = text[0] with freetype_lock: font = symbol_map.get(ch) if font is None or not font.face.get_char_index(ch): font = current_font_family.get( key) or current_font_family['regular'] face = font.face if not face.get_char_index(ch): try: font = font_for_char(ch, bold, italic) except FontNotFound: font = font_for_char(ch, bold, italic, allow_bitmaped_fonts=True) face = alt_face_cache.get(font) if face is None: face = alt_face_cache[font] = Face(font.face, font.index) if face.is_scalable: set_char_size(face, **cff_size) else: face = font.face return render_using_face(font, face, text, width, italic, bold)
def face_for_text(text, bold=False, italic=False): key = 'regular' if bold: key = 'bi' if italic else 'bold' elif italic: key = 'italic' font = symbol_map.get(text[0]) if font is None or not font_has_text(font, text): font = current_font_family.get(key) or current_font_family['regular'] face = font.face if not font_has_text(font, text): try: font = font_for_text(text, bold, italic) except FontNotFound: font = font_for_text(text, bold, italic, allow_bitmaped_fonts=True) face = alt_face_cache.get(font) if face is None: face = alt_face_cache[font] = Face(font.face, font.index, font.hinting, font.hintstyle) if face.is_scalable: set_char_size(face, **cff_size) else: face = font.face return font, face
def do(key): b = get_font_information(family, bold=key in ('bold', 'bi'), italic=key in ('italic', 'bi')) if b.face != n.face: ans[key] = Font(Face(b.face), b.hinting, b.hintstyle, b.bold, b.italic)
def render_char(text, bold=False, italic=False, width=1): key = 'regular' if bold: key = 'bi' if italic else 'bold' elif italic: key = 'italic' with freetype_lock: font = current_font_family.get(key) or current_font_family['regular'] face = font.face if not face.get_char_index(text[0]): font = font_for_char(text[0], bold, italic) face = alt_face_cache.get(font) if face is None: face = alt_face_cache[font] = Face(font.face) set_char_size(face, **cff_size) bitmap = render_to_bitmap(font, face, text) if width == 1 and bitmap.width > cell_width * 1.1: # rescale the font size so that the glyph is visible in a single # cell and hope somebody updates libc's wcwidth sz = cff_size.copy() sz['width'] = int(sz['width'] * cell_width / bitmap.width) # Preserve aspect ratio sz['height'] = int(sz['height'] * cell_width / bitmap.width) try: set_char_size(face, **sz) bitmap = render_to_bitmap(font, face, text) finally: set_char_size(face, **cff_size) m = face.glyph_metrics() return CharBitmap(bitmap.buffer, ceil_int(abs(m.horiBearingX) / 64), ceil_int(abs(m.horiBearingY) / 64), ceil_int(m.horiAdvance / 64), bitmap.rows, bitmap.width)
def do(key): b = get_font_information( get_family(key), bold=key in ('bold', 'bi'), italic=key in ('italic', 'bi') ) if b.face != n.face: ans[key] = b._replace(face=Face(b.face, b.index))
def install_symbol_map(val, font_size, dpi): global symbol_map symbol_map = {} family_map = { f: Face(f, False, False, False, font_size, dpi) for f in set(val.values()) } for ch, family in val.items(): symbol_map[ch] = family_map[family]
def get_font_files(family): ans = {} n = get_font_information(family) ans['regular'] = Font(Face(n.face), n.hinting, n.hintstyle, n.bold, n.italic) def do(key): b = get_font_information(family, bold=key in ('bold', 'bi'), italic=key in ('italic', 'bi')) if b.face != n.face: ans[key] = Font(Face(b.face), b.hinting, b.hintstyle, b.bold, b.italic) do('bold'), do('italic'), do('bi') return ans
def get_face(font_map, family, main_family, font_size, dpi, bold=False, italic=False): def resolve_family(f): if (bold or italic) and f == 'auto': f = main_family if f.lower() == 'monospace': f = 'Menlo' return f descriptor = find_best_match(font_map, resolve_family(family), bold, italic) return Face(descriptor, font_size, dpi)
def set_font_family(opts, override_font_size=None, ignore_dpi_failure=False): global cell_width, cell_height, baseline, CellTexture, WideCellTexture, underline_thickness, underline_position try: dpi = get_logical_dpi() except Exception: if not ignore_dpi_failure: raise dpi = (72, 72) # Happens when running via develop() in an ssh session dpi = sum(dpi) / 2.0 attr_map = { (False, False): 'font_family', (True, False): 'bold_font', (False, True): 'italic_font', (True, True): 'bold_italic_font' } def get_family(bold, italic): ans = getattr(opts, attr_map[(bold, italic)]) if ans.lower() == 'monospace': ans = 'Menlo' if ans == 'auto' and (bold or italic): ans = get_family(False, False) return ans font_size = override_font_size or opts.font_size for bold in (False, True): for italic in (False, True): main_font[(bold, italic)] = Face(get_family(bold, italic), bold, italic, True, font_size, dpi) install_symbol_map(opts.symbol_map, font_size, dpi) mf = main_font[(False, False)] cell_width, cell_height = mf.cell_size() CellTexture = ctypes.c_ubyte * (cell_width * cell_height) WideCellTexture = ctypes.c_ubyte * (2 * cell_width * cell_height) baseline = int(round(mf.ascent)) underline_position = int(round(baseline - mf.underline_position)) underline_thickness = ceil_int(mf.underline_thickness) return cell_width, cell_height
def font_for_family(family): ans = get_font_information(family) return ans._replace(face=Face(ans.face, ans.index))
def font_for_family(family): ans = get_font_information(family) return ans._replace(face=Face(ans.face, ans.index, ans.hinting, ans.hintstyle))