def render_using_face(font, face, text, width, italic, bold): bitmap = render_to_bitmap(font, face, text) if width == 1 and bitmap.width > cell_width: extra = bitmap.width - cell_width if italic and extra < cell_width // 2: bitmap = face.trim_to_width(bitmap, cell_width) elif extra > max(2, 0.3 * cell_width) and face.is_scalable: # 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 set_font_family(opts, override_font_size=None): global current_font_family, current_font_family_name, cff_size, cell_width, cell_height, CharTexture, baseline global underline_position, underline_thickness size_in_pts = override_font_size or opts.font_size current_font_family = get_font_files(opts) current_font_family_name = opts.font_family dpi = get_logical_dpi() cff_size = ceil_int(64 * size_in_pts) cff_size = { 'width': cff_size, 'height': cff_size, 'hres': int(dpi[0]), 'vres': int(dpi[1]) } install_symbol_map(opts.symbol_map) for fobj in chain(current_font_family.values(), symbol_map.values()): set_char_size(fobj.face, **cff_size) face = current_font_family['regular'].face cell_width = face.calc_cell_width() cell_height = font_units_to_pixels(face.height, face.units_per_EM, size_in_pts, dpi[1]) cell_height = adjust_line_height(cell_height, opts.adjust_line_height) baseline = font_units_to_pixels(face.ascender, face.units_per_EM, size_in_pts, dpi[1]) underline_position = min( baseline - font_units_to_pixels( face.underline_position, face.units_per_EM, size_in_pts, dpi[1]), cell_height - 1) underline_thickness = font_units_to_pixels(face.underline_thickness, face.units_per_EM, size_in_pts, dpi[1]) CharTexture = ctypes.c_ubyte * (cell_width * cell_height) font_for_text.cache_clear() alt_face_cache.clear() return cell_width, cell_height
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 font_size = override_font_size or opts.font_size all_fonts = create_font_map(coretext_all_fonts()) for (bold, italic), attr in attr_map.items(): main_font[(bold, italic)] = get_face(all_fonts, getattr(opts, attr), opts.font_family, font_size, dpi, bold, italic) install_symbol_map(all_fonts, opts.symbol_map, font_size, dpi) mf = main_font[(False, False)] cell_width, cell_height = mf.cell_size() cell_height = adjust_line_height(cell_height, opts.adjust_line_height) 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 calc_cell_width(font, face): ans = 0 for i in range(32, 128): ch = chr(i) load_char(font, face, ch) m = face.glyph_metrics() ans = max(ans, ceil_int(m.horiAdvance / 64)) return ans
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_units_to_pixels(x, units_per_em, size_in_pts, dpi): return ceil_int(x * ((size_in_pts * dpi) / (72 * units_per_em)))