def _get_agg_font(self, prop): """ Get the font for text instance t, cacheing for efficiency """ if __debug__: verbose.report('RendererAgg._get_agg_font', 'debug-annoying') key = hash(prop) font = RendererAgg._fontd.get(key) if font is None: fname = findfont(prop) font = RendererAgg._fontd.get(fname) if font is None: font = FT2Font( fname, hinting_factor=rcParams['text.hinting_factor']) RendererAgg._fontd[fname] = font RendererAgg._fontd[key] = font font.clear() size = prop.get_size_in_points() font.set_size(size, self.dpi) return font
def _write_svgfonts(self): if not rcParams['svg.fonttype'] == 'svgfont': return writer = self.writer writer.start('defs') for font_fname, chars in list(self._fonts.items()): font = FT2Font(font_fname) font.set_size(72, 72) sfnt = font.get_sfnt() writer.start('font', id=sfnt[(1, 0, 0, 4)]) writer.element('font-face', attrib={ 'font-family': font.family_name, 'font-style': font.style_name.lower(), 'units-per-em': '72', 'bbox': ' '.join(str(x / 64.0) for x in font.bbox) }) for char in chars: glyph = font.load_char(char, flags=LOAD_NO_HINTING) verts, codes = font.get_path() path = Path(verts, codes) path_data = self._convert_path(path) # name = font.get_glyph_name(char) writer.element( 'glyph', d=path_data, attrib={ # 'glyph-name': name, 'unicode': chr(char), 'horiz-adv-x': str(glyph.linearHoriAdvance / 65536.0) }) writer.end('font') writer.end('defs')
def __init__(self): # inspect all the fonts in the current path and make a dict # from font type (tt, rm, it, cal) -> unicode chars that it # provides self.glyphd = {} self.fonts = dict([ (name, FT2Font(os.path.join(self.basepath, name) + '.ttf')) for name in self.fnames ]) self.charmaps = dict([(name, self.fonts[name].get_charmap()) for name in self.fnames]) # glyphmaps is a dict names to a dict of charcode -> glyphindex self.glyphmaps = {} for name in self.fnames: cmap = self.charmaps[name] self.glyphmaps[name] = dict([(ccode, glyphind) for glyphind, ccode in cmap.items()]) for font in self.fonts.values(): font.clear() if useSVG: self.svg_glyphs = [ ] # a list of "glyphs" we need to render this thing in SVG else: pass self.usingSVG = useSVG
def _get_font_ttf(self, prop): font = self.fonts.get(prop) if font is None: font = FT2Font(fontManager.findfont(prop)) self.fonts[prop] = font font.clear() font.set_size(prop.get_size_in_points(), 72.0) return font
def __init__(self): self.glyphd = {} self.fonts = dict( [ (name, FT2Font(os.path.join(self.basepath, name) + '.ttf')) for name in self.fnames]) for font in self.fonts.values(): font.clear()
def _get_font(self, prop): """ find a ttf font. """ fname = font_manager.findfont(prop) font = FT2Font(str(fname)) font.set_size(self.FONT_SCALE, self.DPI) return font
def draw_font_table(path): """ Draw a font table of the first 255 chars of the given font. Parameters ---------- path : str or None The path to the font file. If None, use Matplotlib's default font. """ if path is None: path = fm.findfont(fm.FontProperties()) # The default font. font = FT2Font(path) # A charmap is a mapping of "character codes" (in the sense of a character # encoding, e.g. latin-1) to glyph indices (i.e. the internal storage table # of the font face). # In FreeType>=2.1, a Unicode charmap (i.e. mapping Unicode codepoints) # is selected by default. Moreover, recent versions of FreeType will # automatically synthesize such a charmap if the font does not include one # (this behavior depends on the font format; for example it is present # since FreeType 2.0 for Type 1 fonts but only since FreeType 2.8 for # TrueType (actually, SFNT) fonts). # The code below (specifically, the ``chr(char_code)`` call) assumes that # we have indeed selected a Unicode charmap. codes = font.get_charmap().items() labelc = ["{:X}".format(i) for i in range(16)] labelr = ["{:02X}".format(16 * i) for i in range(16)] chars = [["" for c in range(16)] for r in range(16)] for char_code, glyph_index in codes: if char_code >= 256: continue row, col = divmod(char_code, 16) chars[row][col] = chr(char_code) fig, ax = plt.subplots(figsize=(8, 4)) ax.set_title(os.path.basename(path)) ax.set_axis_off() table = ax.table( cellText=chars, rowLabels=labelr, colLabels=labelc, rowColours=["palegreen"] * 16, colColours=["palegreen"] * 16, cellColours=[[".95" for c in range(16)] for r in range(16)], cellLoc='center', loc='upper left', ) for key, cell in table.get_celld().items(): row, col = key if row > 0 and col > -1: # Beware of table's idiosyncratic indexing... cell.set_text_props(font=Path(path)) fig.tight_layout() plt.show()
def _get_font(self, prop): key = hash(prop) font = _fontd.get(key) if font is None: fname = fontManager.findfont(prop) font = FT2Font(str(fname)) _fontd[key] = font font.clear() size = prop.get_size_in_points() font.set_size(size, 72.0) return font
def _get_font(self, prop): key = hash(prop) font = _fontd.get(key) if font is None: fname = fontManager.findfont(prop) try: font = FT2Font(str(fname)) except RuntimeError, msg: verbose.report_error('Could not load filename for text "%s"'%fname) return None else: _fontd[key] = font
def _get_font(self, prop): key = hash(prop) font = self.fontd.get(key) if font is None: fname = findfont(prop) font = self.fontd.get(fname) if font is None: font = FT2Font(str(fname)) self.fontd[fname] = font self.fontd[key] = font font.clear() font.set_size(prop.get_size_in_points(), self.dpi) return font
def test_glyphs_subset(): fpath = str(_get_data_path("fonts/ttf/DejaVuSerif.ttf")) chars = "these should be subsetted! 1234567890" # non-subsetted FT2Font nosubfont = FT2Font(fpath) nosubfont.set_text(chars) # subsetted FT2Font subfont = FT2Font(get_glyphs_subset(fpath, chars)) subfont.set_text(chars) nosubcmap = nosubfont.get_charmap() subcmap = subfont.get_charmap() # all unique chars must be available in subsetted font assert set(chars) == set(chr(key) for key in subcmap.keys()) # subsetted font's charmap should have less entries assert len(subcmap) < len(nosubcmap) # since both objects are assigned same characters assert subfont.get_num_glyphs() == nosubfont.get_num_glyphs()
def _get_font(self, prop): key = hash(prop) font = _fontd.get(key) if font is None: fname = fontManager.findfont(prop) try: font = FT2Font(str(fname)) except RuntimeError, msg: print >> sys.stderr, 'Could not load filename for text', fname return None else: _fontd[key] = font if fname not in _type42: _type42.append(fname)
def __init__(self, useSVG=False): self.glyphd = {} self.fonts = dict([ (name, FT2Font(os.path.join(self.basepath, name) + '.ttf')) for name in self.fnames ]) for font in self.fonts.values(): font.clear() if useSVG: self.svg_glyphs = [ ] # a list of "glyphs" we need to render this thing in SVG else: pass self.usingSVG = useSVG
def DISABLED_memleak( self ): """Test agg backend for memory leaks.""" fontname = '/usr/local/share/matplotlib/Vera.ttf' fname = self.outFile( "agg_memleak_%05d.png" ) N = 200 for i in range( N ): gc = GraphicsContextBase() gc.set_clip_rectangle( [20, 20, 20, 20] ) o = RendererAgg( 400, 400, 72 ) for j in range( 50 ): xs = [ 400*int(rand()) for k in range(8) ] ys = [ 400*int(rand()) for k in range(8) ] rgb = (1, 0, 0) pnts = zip( xs, ys ) o.draw_polygon( gc, rgb, pnts ) o.draw_polygon( gc, None, pnts ) for j in range( 50 ): x = [ 400*int(rand()) for k in range(4) ] y = [ 400*int(rand()) for k in range(4) ] o.draw_lines( gc, x, y ) for j in range( 50 ): args = [ 400*int(rand()) for k in range(4) ] rgb = (1, 0, 0) o.draw_rectangle( gc, rgb, *args ) if 1: # add text font = FT2Font( fontname ) font.clear() font.set_text( 'hi mom', 60 ) font.set_size( 12, 72 ) o.draw_text_image( font.get_image(), 30, 40, gc ) o.write_png( fname % i ) val = report_memory( i ) if i==1: start = val end = val avgMem = (end - start) / float(N) print 'Average memory consumed per loop: %1.4f\n' % (avgMem) #TODO: Verify the expected mem usage and approximate tolerance that should be used self.checkClose( 0.32, avgMem, absTol = 0.1 )
def test_find_invalid(tmpdir): tmp_path = Path(tmpdir) with pytest.raises(FileNotFoundError): get_font(tmp_path / 'non-existent-font-name.ttf') with pytest.raises(FileNotFoundError): get_font(str(tmp_path / 'non-existent-font-name.ttf')) with pytest.raises(FileNotFoundError): get_font(bytes(tmp_path / 'non-existent-font-name.ttf')) # Not really public, but get_font doesn't expose non-filename constructor. from matplotlib.ft2font import FT2Font with pytest.raises(TypeError, match='path or binary-mode file'): FT2Font(StringIO())
def _get_font(self, prop): key = hash(prop) font_value = self.fontd.get(key) if font_value is None: fname = findfont(prop) font_value = self.fontd.get(fname) if font_value is None: font = FT2Font(str(fname)) font_file_name = fname[fname.rfind("/") + 1:] font_value = font, font_file_name self.fontd[fname] = font_value self.fontd[key] = font_value font, font_file_name = font_value font.clear() font.set_size(prop.get_size_in_points(), self.dpi) return font, font_file_name
def _get_font_ttf(self, prop): """ get the true type font properties, used because EMFs on windows will use true type fonts. """ key = hash(prop) font = _fontd.get(key) if font is None: fname = findfont(prop) if debugText: print "_get_font_ttf: name=%s" % fname font = FT2Font(str(fname)) _fontd[key] = font font.clear() size = prop.get_size_in_points() font.set_size(size, self.dpi) return font
def _get_agg_font(self, prop): """ Get the font for text instance t, cacheing for efficiency """ if __debug__: verbose.report('RendererAgg._get_agg_font', 'debug-annoying') key = hash(prop) font = _fontd.get(key) if font is None: fname = fontManager.findfont(prop) font = FT2Font(str(fname)) _fontd[key] = font font.clear() size = prop.get_size_in_points() font.set_size(size, self.dpi.get()) return font
def print_glyphs(path): """ Print the all glyphs in the given font file to stdout. Parameters ---------- path : str or None The path to the font file. If None, use Matplotlib's default font. """ if path is None: path = fm.findfont(fm.FontProperties()) # The default font. font = FT2Font(path) charmap = font.get_charmap() max_indices_len = len(str(max(charmap.values()))) print("The font face contains the following glyphs:") for char_code, glyph_index in charmap.items(): char = chr(char_code) name = unicodedata.name( char, f"{char_code:#x} ({font.get_glyph_name(glyph_index)})") print(f"{glyph_index:>{max_indices_len}} {char} {name}")
def __init__(self, useSVG=False): self.glyphd = {} self.fonts = dict([ (name, FT2Font(os.path.join(self.basepath, name) + '.ttf')) for name in self.fnames ]) self.charmaps = dict([(name, self.fonts[name].get_charmap()) for name in self.fnames]) # glyphmaps is a dict names to a dict of charcode -> glyphindex self.glyphmaps = {} for name in self.fnames: cmap = self.charmaps[name] self.glyphmaps[name] = dict([(ccode, glyphind) for glyphind, ccode in cmap.items()]) for font in self.fonts.values(): font.clear() if useSVG: self.svg_glyphs = [ ] # a list of "glyphs" we need to render this thing in SVG else: pass self.usingSVG = useSVG
def _font_to_ps_type42(font_path, chars, fh): """ Subset *chars* from the font at *font_path* into a Type 42 font at *fh*. Parameters ---------- font_path : path-like Path to the font to be subsetted. chars : str The characters to include in the subsetted font. fh : file-like Where to write the font. """ subset_str = ''.join(chr(c) for c in chars) _log.debug("SUBSET %s characters: %s", font_path, subset_str) try: fontdata = _backend_pdf_ps.get_glyphs_subset(font_path, subset_str) _log.debug("SUBSET %s %d -> %d", font_path, os.stat(font_path).st_size, fontdata.getbuffer().nbytes) # Give ttconv a subsetted font along with updated glyph_ids. font = FT2Font(fontdata) glyph_ids = [font.get_char_index(c) for c in chars] with TemporaryDirectory() as tmpdir: tmpfile = os.path.join(tmpdir, "tmp.ttf") with open(tmpfile, 'wb') as tmp: tmp.write(fontdata.getvalue()) # TODO: allow convert_ttf_to_ps to input file objects (BytesIO) convert_ttf_to_ps(os.fsencode(tmpfile), fh, 42, glyph_ids) except RuntimeError: _log.warning("The PostScript backend does not currently " "support the selected font.") raise
def plot_graph(self, title=None, file='graph.png'): from matplotlib.font_manager import _rebuild _rebuild() font_path = '' if platform.system() is 'Windows': # Window의 경우 폰트 경로 font_path = 'C:/Windows/Fonts/malgun.ttf' elif platform.system() is 'Darwin': # for Mac font_path = '/Library/Fonts/AppleGothic.ttf' font_name = fm.FontProperties(fname=font_path).get_name() plt.rc('font', family=font_name) plt.rc('axes', unicode_minus=False) # 그래프에서 마이너스 폰트 깨지는 문제에 대한 대처 mpl.rcParams['axes.unicode_minus'] = False #print('버전: ', mpl.__version__) #print('설치 위치: ', mpl.__file__) #print('설정 위치: ', mpl.get_configdir()) #print('캐시 위치: ', mpl.get_cachedir()) # size, family print('# 설정 되어있는 폰트 사이즈') print(plt.rcParams['font.size']) print('# 설정 되어있는 폰트 글꼴') print(plt.rcParams['font.family']) fig = plt.figure(figsize=(8, 8)) pos = self.centrality_layout() """Conveniently summarize graph visually""" # config parameters edge_min_width = 3 edge_max_width = 12 label_font = 18 node_font = 22 node_alpha = 0.4 edge_alpha = 0.55 edge_cmap = plt.cm.Spectral # Create figure if fig is None: fig, ax = plt.subplots() else: ax = fig.add_subplot(111) fig.subplots_adjust(0, 0, 1) font = FT2Font(font_path) # Plot nodes with size according to count sizes = [] degrees = [] for n, d in self.G.nodes(data=True): sizes.append(d['count']) degrees.append(self.G.degree(n)) sizes = self.rescale_arr(np.array(sizes, dtype=float), 100, 1000) # Compute layout and label edges according to weight pos = nx.spring_layout(self.G) if pos is None else pos labels = {} width = [] for n1, n2, d in self.G.edges(data=True): w = d['weight'] labels[n1, n2] = w width.append(w) width = self.rescale_arr(np.array(width, dtype=float), edge_min_width, edge_max_width) # Draw nx.draw_networkx_nodes(self.G, pos, node_size=sizes, node_color=degrees, alpha=node_alpha) nx.draw_networkx_edges(self.G, pos, width=width, edge_color=width, edge_cmap=edge_cmap, alpha=edge_alpha) nx.draw_networkx_edge_labels(self.G, pos, edge_labels=labels, font_size=label_font) nx.draw_networkx_labels(self.G, pos, font_size=node_font, font_family=font_name, font_weight='bold') if title is not None: ax.set_title(title, fontsize=label_font) ax.set_xticks([]) ax.set_yticks([]) # Mark centrality axes kw = dict(color='k', linestyle='-') cross = [ax.axhline(0, **kw), ax.axvline(self.rad0, **kw)] [l.set_zorder(0) for l in cross] #plt.show() plt.savefig(file)
from matplotlib import _png, rcParams from matplotlib.cbook import is_string_like, is_writable_file_like from matplotlib.compat import subprocess from matplotlib.compat.subprocess import check_output ############################################################################### # create a list of system fonts, all of these should work with xe/lua-latex system_fonts = [] if sys.platform.startswith('win'): from matplotlib import font_manager from matplotlib.ft2font import FT2Font for f in font_manager.win32InstalledFonts(): try: system_fonts.append(FT2Font(str(f)).family_name) except: pass # unknown error, skip this font else: # assuming fontconfig is installed and the command 'fc-list' exists try: # list scalable (non-bitmap) fonts fc_list = check_output(['fc-list', ':outline,scalable', 'family']) fc_list = fc_list.decode('utf8') system_fonts = [f.split(',')[0] for f in fc_list.splitlines()] system_fonts = list(set(system_fonts)) except: warnings.warn('error getting fonts from fc-list', UserWarning) def get_texcommand(): """Get chosen TeX system from rc."""
def encodeTTFasPS(fontfile): """ Encode a TrueType font file for embedding in a PS file. """ fontfile = str(fontfile) # todo: handle unicode filenames font = file(fontfile, 'rb') hexdata, data = '', font.read(65520) while len(data): hexdata += '<'+'\n'.join([binascii.b2a_hex(data[j:j+36]).upper() \ for j in range(0, len(data), 36)])+'>\n' data = font.read(65520) hexdata = hexdata[:-2] + '00>' font = FT2Font(fontfile) headtab = font.get_sfnt_table('head') version = '%d.%d' % headtab['version'] revision = '%d.%d' % headtab['fontRevision'] dictsize = 8 fontname = font.postscript_name encoding = 'StandardEncoding' fontbbox = '[%d %d %d %d]' % font.bbox posttab = font.get_sfnt_table('post') minmemory = posttab['minMemType42'] maxmemory = posttab['maxMemType42'] infosize = 7 sfnt = font.get_sfnt() notice = sfnt[(1, 0, 0, 0)] family = sfnt[(1, 0, 0, 1)] fullname = sfnt[(1, 0, 0, 4)] iversion = sfnt[(1, 0, 0, 5)] fixpitch = str(bool(posttab['isFixedPitch'])).lower() ulinepos = posttab['underlinePosition'] ulinethk = posttab['underlineThickness'] italicang = '(%d.%d)' % posttab['italicAngle'] numglyphs = font.num_glyphs glyphs = '' for j in range(numglyphs): glyphs += '/%s %d def' % (font.get_glyph_name(j), j) if j != 0 and j % 4 == 0: glyphs += '\n' else: glyphs += ' ' data = '%%!PS-TrueType-%(version)s-%(revision)s\n' % locals() if maxmemory: data += '%%%%VMusage: %(minmemory)d %(maxmemory)d' % locals() data += """%(dictsize)d dict begin /FontName /%(fontname)s def /FontMatrix [1 0 0 1 0 0] def /FontType 42 def /Encoding %(encoding)s def /FontBBox %(fontbbox)s def /PaintType 0 def /FontInfo %(infosize)d dict dup begin /Notice (%(notice)s) def /FamilyName (%(family)s) def /FullName (%(fullname)s) def /version (%(iversion)s) def /isFixedPitch %(fixpitch)s def /UnderlinePosition %(ulinepos)s def /UnderlineThickness %(ulinethk)s def end readonly def /sfnts [ %(hexdata)s ] def /CharStrings %(numglyphs)d dict dup begin %(glyphs)s end readonly def FontName currentdict end definefont pop""" % locals() return data
def draw_font_table(path, data=None): """ Draw a font table of the first 255 chars of the given font. Parameters ---------- path : str or None The path to the font file. If None, use Matplotlib's default font. """ if path is None: path = fm.findfont(fm.FontProperties()) # The default font. font = FT2Font(path) # A charmap is a mapping of "character codes" (in the sense of a character # encoding, e.g. latin-1) to glyph indices (i.e. the internal storage table # of the font face). # In FreeType>=2.1, a Unicode charmap (i.e. mapping Unicode codepoints) # is selected by default. Moreover, recent versions of FreeType will # automatically synthesize such a charmap if the font does not include one # (this behavior depends on the font format; for example it is present # since FreeType 2.0 for Type 1 fonts but only since FreeType 2.8 for # TrueType (actually, SFNT) fonts). # The code below (specifically, the ``chr(char_code)`` call) assumes that # we have indeed selected a Unicode charmap. codes = font.get_charmap().items() i = 0 c_list = {"name": data[0]["date"].split("T")[0], # "stockCode":"指数代码", "wai": "场外代码", # "index":"index", "nei":"场内代码", "pe_ttm_y_10_weightedAvg_latestVal": "PE", "pe_ttm_y_10_weightedAvg_latestValPos": "PE百分位", # "pe_ttm_y_10_weightedAvg_minVal": "PE区间下限", # "pe_ttm_y_10_weightedAvg_maxVal": "PE区间上限", # "pe_ttm_y_10_weightedAvg_riskVal": "PE危险点", # "pe_ttm_y_10_weightedAvg_chanceVal": "PE机会点", "pb_y_10_weightedAvg_latestVal": "PB", "pb_y_10_weightedAvg_latestValPos": "PB百分位", # "ps_ttm_y_10_weightedAvg_latestVal": "PS", # "ps_ttm_y_10_weightedAvg_latestValPos": "PS百分位", "dyr_weightedAvg": "股息率", } for check_num in range(1,4): main_index=1 fig, ax = plt.subplots(figsize=(10, 5)) # 大小 if data: labelc = list(c_list.values()) labelw = [] chars = [] cellColours = [] for solo in data: #排序 val = solo["pe_ttm_y_10_weightedAvg_latestVal"] good = solo["pe_ttm_y_10_weightedAvg_chanceVal"] bad = solo["pe_ttm_y_10_weightedAvg_riskVal"] value_list = [solo["pe_ttm_y_10_weightedAvg_latestVal"], solo["pe_ttm_y_10_weightedAvg_chanceVal"], solo["pe_ttm_y_10_weightedAvg_riskVal"], solo["pb_y_10_weightedAvg_latestVal"], solo["pb_y_10_weightedAvg_chanceVal"], solo["pb_y_10_weightedAvg_riskVal"], solo["ps_ttm_y_10_weightedAvg_latestVal"], solo["ps_ttm_y_10_weightedAvg_chanceVal"], solo["ps_ttm_y_10_weightedAvg_riskVal"], ] result = {"good":0,"bad":0,"other":0} for index in range(0, len(value_list), 3): if value_list[index] < value_list[index + 1]: result["good"] += 1 elif value_list[index + 1] < value_list[index] < value_list[index + 2]: result["other"] += 1 else: result["bad"] += 1 if result["good"] >= check_num: solo["sort"] = 0 else: if result["other"] > result["bad"]: solo["sort"] = 1 else: solo["sort"] = 2 if val > bad: solo["sort"] = 2 data.sort(key=getPoint) for solo_data in data: if solo_data["stockCode"] not in data_temp.keys(): continue print(solo_data["stockCode"]) solo_data["index"] = main_index main_index+=1 solo_data["wai"] = data_temp[solo_data["stockCode"]]["wai"] solo_data["nei"] = data_temp[solo_data["stockCode"]]["nei"] temp = [] color = [] width = [] for key in c_list: if key in solo_data.keys(): if "Pos" in key or "dyr_weightedAvg"==key: temp.append('%.2f%%'%(solo_data[key]*100)) elif key == "pe_ttm_y_10_weightedAvg_latestVal": temp.append('%.2f'%solo_data[key]) elif key == "pb_y_10_weightedAvg_latestVal": temp.append('%.2f' % solo_data[key]) else: temp.append(solo_data[key]) else: temp.append("") if solo_data["sort"]==0: color.append('green') elif solo_data["sort"]==1: color.append("yellow") else: color.append("red") width.append(2) chars.append(temp) cellColours.append(color) # labelw.append(0.2) ax.set_axis_off() table = ax.table( cellText=chars, # rowLabels=labelr, colLabels=labelc, # cellColours=[[".95" for c in range(16)] for r in range(16)], cellColours=cellColours, # colWidths=labelw, cellLoc='center', edges="BRTL", # 边框 BRTL loc='upper left', ) table.auto_set_font_size(False) table.set_fontsize(2) # table.scale(2, 2) for key, cell in table.get_celld().items(): row, col = key if row > -1 and col > -1: # 塞数据 cell.set_text_props(fontproperties=fm.FontProperties(fname=path)) fig.tight_layout() plt.savefig(str(check_num)+".png") plt.close() ff = open(str(check_num)+"d.csv", "w", encoding='utf-8-sig') writer = csv.writer(ff) writer.writerows(chars) ff.close()
def print_figure(self, outfile, dpi=72, facecolor='w', edgecolor='w', orientation='portrait'): """ Render the figure to hardcopy. Set the figure patch face and edge colors. This is useful because some of the GUIs have a gray figure face color background and you'll probably want to override this on hardcopy If outfile is a string, it is interpreted as a file name. If the extension matches .ep* write encapsulated postscript, otherwise write a stand-alone PostScript file. If outfile is a file object, a stand-alone PostScript file is written into this file object. """ if isinstance(outfile, file): # assume plain PostScript and write to fileobject isEPSF = False fh = outfile needsClose = False title = None else: basename, ext = os.path.splitext(outfile) if not ext: outfile += '.ps' isEPSF = ext.lower().startswith('.ep') fh = file(outfile, 'w') needsClose = True title = outfile # center the figure on the paper self.figure.dpi.set(72) # ignore the passsed dpi setting for PS width, height = self.figure.get_size_inches() if orientation == 'landscape': isLandscape = True paperHeight, paperWidth = defaultPaperSize else: isLandscape = False paperWidth, paperHeight = defaultPaperSize xo = 72 * 0.5 * (paperWidth - width) yo = 72 * 0.5 * (paperHeight - height) l, b, w, h = self.figure.bbox.get_bounds() llx = xo lly = yo urx = llx + w ury = lly + h if isLandscape: xo, yo = 72 * paperHeight - yo, xo llx, lly, urx, ury = lly, llx, ury, urx rotation = 90 else: rotation = 0 # generate PostScript code for the figure and store it in a string origfacecolor = self.figure.get_facecolor() origedgecolor = self.figure.get_edgecolor() self.figure.set_facecolor(facecolor) self.figure.set_edgecolor(edgecolor) self._pswriter = StringIO() renderer = RendererPS(width, height, self._pswriter) self.figure.draw(renderer) self.figure.set_facecolor(origfacecolor) self.figure.set_edgecolor(origedgecolor) # write the PostScript headers if isEPSF: print >> fh, "%!PS-Adobe-3.0 EPSF-3.0" else: print >> fh, "%!PS-Adobe-3.0" if title: print >> fh, "%%Title: " + title print >> fh, ("%%Creator: matplotlib version " + __version__ + ", http://matplotlib.sourceforge.net/") print >> fh, "%%CreationDate: " + time.ctime(time.time()) if not isEPSF: if paperWidth > paperHeight: ostr = "Landscape" else: ostr = "Portrait" print >> fh, "%%Orientation: " + ostr print >> fh, "%%%%BoundingBox: %d %d %d %d" % (llx, lly, urx, ury) if not isEPSF: print >> fh, "%%Pages: 1" print >> fh, "%%EndComments" type42 = _type42 + [os.path.join(self.basepath, name) + '.ttf' \ for name in bakoma_fonts] print >> fh, "%%BeginProlog" print >> fh, "/mpldict %d dict def" % (len(_psDefs) + len(type42)) print >> fh, "mpldict begin" for d in _psDefs: d = d.strip() for l in d.split('\n'): print >> fh, l.strip() for font in type42: font = str(font) # TODO: handle unicode filenames print >> fh, "%%BeginFont: " + FT2Font(font).postscript_name print >> fh, encodeTTFasPS(font) print >> fh, "%%EndFont" print >> fh, "%%EndProlog" if not isEPSF: print >> fh, "%%Page: 1 1" print >> fh, "mpldict begin" print >> fh, "gsave" print >> fh, "%s translate" % _nums_to_str(xo, yo) if rotation: print >> fh, "%d rotate" % rotation print >> fh, "%s clipbox" % _nums_to_str(width * 72, height * 72, 0, 0) # write the figure print >> fh, self._pswriter.getvalue() # write the trailer print >> fh, "grestore" print >> fh, "end" print >> fh, "showpage" if not isEPSF: print >> fh, "%%EOF" if needsClose: fh.close()
""" A little example that shows how the various indexing into the font tables relate to one another. Mainly for mpl developers.... """ from __future__ import print_function import matplotlib from matplotlib.ft2font import FT2Font, KERNING_DEFAULT, KERNING_UNFITTED, KERNING_UNSCALED #fname = '/usr/share/fonts/sfd/FreeSans.ttf' fname = matplotlib.get_data_path() + '/fonts/ttf/DejaVuSans.ttf' font = FT2Font(fname) font.set_charmap(0) codes = font.get_charmap().items() #dsu = [(ccode, glyphind) for ccode, glyphind in codes] #dsu.sort() #for ccode, glyphind in dsu: # try: name = font.get_glyph_name(glyphind) # except RuntimeError: pass # else: print('% 4d % 4d %s %s' % (glyphind, ccode, hex(int(ccode)), name)) # make a charname to charcode and glyphind dictionary coded = {} glyphd = {} for ccode, glyphind in codes: name = font.get_glyph_name(glyphind) coded[name] = ccode glyphd[name] = glyphind
def get_glyphs_tex(self, prop, s, glyph_map=None, return_new_glyphs_only=False): """ convert the string *s* to vertices and codes using matplotlib's usetex mode. """ # codes are modstly borrowed from pdf backend. texmanager = self.get_texmanager() if self.tex_font_map is None: self.tex_font_map = dviread.PsfontsMap( dviread.find_tex_file('pdftex.map')) fontsize = prop.get_size_in_points() if hasattr(texmanager, "get_dvi"): # dvifilelike = texmanager.get_dvi(s, self.FONT_SCALE) dvi = dviread.DviFromFileLike(dvifilelike, self.DPI) else: dvifile = texmanager.make_dvi(s, self.FONT_SCALE) dvi = dviread.Dvi(dvifile, self.DPI) page = iter(dvi).next() dvi.close() if glyph_map is None: glyph_map = dict() if return_new_glyphs_only: glyph_map_new = dict() else: glyph_map_new = glyph_map glyph_ids, xpositions, ypositions, sizes = [], [], [], [] # Gather font information and do some setup for combining # characters into strings. #oldfont, seq = None, [] for x1, y1, dvifont, glyph, width in page.text: font_and_encoding = self._ps_fontd.get(dvifont.texname) if font_and_encoding is None: font_bunch = self.tex_font_map[dvifont.texname] font = FT2Font(str(font_bunch.filename)) try: font.select_charmap(1094992451) # select ADOBE_CUSTOM except ValueError: font.set_charmap(0) if font_bunch.encoding: enc = dviread.Encoding(font_bunch.encoding) else: enc = None self._ps_fontd[dvifont.texname] = font, enc else: font, enc = font_and_encoding ft2font_flag = LOAD_TARGET_LIGHT char_id = self._get_char_id_ps(font, glyph) if not char_id in glyph_map: font.clear() font.set_size(self.FONT_SCALE, self.DPI) glyph0 = font.load_char(glyph, flags=ft2font_flag) glyph_map_new[char_id] = self.glyph_to_path(glyph0) glyph_ids.append(char_id) xpositions.append(x1) ypositions.append(y1) sizes.append(dvifont.size / self.FONT_SCALE) myrects = [] for ox, oy, h, w in page.boxes: vert1 = [(ox, oy), (ox + w, oy), (ox + w, oy + h), (ox, oy + h), (ox, oy), (0, 0)] code1 = [ Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY ] myrects.append((vert1, code1)) return zip(glyph_ids, xpositions, ypositions, sizes), \ glyph_map_new, myrects
def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w', orientation='portrait', isLandscape=False, papertype=None): """ Render the figure to hardcopy. Set the figure patch face and edge colors. This is useful because some of the GUIs have a gray figure face color background and you'll probably want to override this on hardcopy If outfile is a string, it is interpreted as a file name. If the extension matches .ep* write encapsulated postscript, otherwise write a stand-alone PostScript file. If outfile is a file object, a stand-alone PostScript file is written into this file object. """ isEPSF = format == 'eps' passed_in_file_object = False if is_string_like(outfile): title = outfile tmpfile = os.path.join(gettempdir(), md5(outfile).hexdigest()) elif is_writable_file_like(outfile): title = None tmpfile = os.path.join(gettempdir(), md5(str(hash(outfile))).hexdigest()) passed_in_file_object = True else: raise ValueError("outfile must be a path or a file-like object") fh = file(tmpfile, 'w') # find the appropriate papertype width, height = self.figure.get_size_inches() if papertype == 'auto': if isLandscape: papertype = _get_papertype(height, width) else: papertype = _get_papertype(width, height) if isLandscape: paperHeight, paperWidth = papersize[papertype] else: paperWidth, paperHeight = papersize[papertype] if rcParams['ps.usedistiller'] and not papertype == 'auto': # distillers will improperly clip eps files if the pagesize is # too small if width > paperWidth or height > paperHeight: if isLandscape: papertype = _get_papertype(height, width) paperHeight, paperWidth = papersize[papertype] else: papertype = _get_papertype(width, height) paperWidth, paperHeight = papersize[papertype] # center the figure on the paper xo = 72 * 0.5 * (paperWidth - width) yo = 72 * 0.5 * (paperHeight - height) l, b, w, h = self.figure.bbox.bounds llx = xo lly = yo urx = llx + w ury = lly + h rotation = 0 if isLandscape: llx, lly, urx, ury = lly, llx, ury, urx xo, yo = 72 * paperHeight - yo, xo rotation = 90 bbox = (llx, lly, urx, ury) # generate PostScript code for the figure and store it in a string origfacecolor = self.figure.get_facecolor() origedgecolor = self.figure.get_edgecolor() self.figure.set_facecolor(facecolor) self.figure.set_edgecolor(edgecolor) self._pswriter = StringIO() renderer = RendererPS(width, height, self._pswriter, imagedpi=dpi) self.figure.draw(renderer) self.figure.set_facecolor(origfacecolor) self.figure.set_edgecolor(origedgecolor) # write the PostScript headers if isEPSF: print >> fh, "%!PS-Adobe-3.0 EPSF-3.0" else: print >> fh, "%!PS-Adobe-3.0" if title: print >> fh, "%%Title: " + title print >> fh, ("%%Creator: matplotlib version " + __version__ + ", http://matplotlib.sourceforge.net/") print >> fh, "%%CreationDate: " + time.ctime(time.time()) print >> fh, "%%Orientation: " + orientation if not isEPSF: print >> fh, "%%DocumentPaperSizes: " + papertype print >> fh, "%%%%BoundingBox: %d %d %d %d" % bbox if not isEPSF: print >> fh, "%%Pages: 1" print >> fh, "%%EndComments" Ndict = len(psDefs) print >> fh, "%%BeginProlog" if not rcParams['ps.useafm']: Ndict += len(renderer.used_characters) print >> fh, "/mpldict %d dict def" % Ndict print >> fh, "mpldict begin" for d in psDefs: d = d.strip() for l in d.split('\n'): print >> fh, l.strip() if not rcParams['ps.useafm']: for font_filename, chars in renderer.used_characters.values(): if len(chars): font = FT2Font(font_filename) cmap = font.get_charmap() glyph_ids = [] for c in chars: gind = cmap.get(c) or 0 glyph_ids.append(gind) # The ttf to ps (subsetting) support doesn't work for # OpenType fonts that are Postscript inside (like the # STIX fonts). This will simply turn that off to avoid # errors. if is_opentype_cff_font(font_filename): raise RuntimeError( "OpenType CFF fonts can not be saved using the internal Postscript backend at this time.\nConsider using the Cairo backend." ) else: fonttype = rcParams['ps.fonttype'] convert_ttf_to_ps(font_filename, fh, rcParams['ps.fonttype'], glyph_ids) print >> fh, "end" print >> fh, "%%EndProlog" if not isEPSF: print >> fh, "%%Page: 1 1" print >> fh, "mpldict begin" #print >>fh, "gsave" print >> fh, "%s translate" % _nums_to_str(xo, yo) if rotation: print >> fh, "%d rotate" % rotation print >> fh, "%s clipbox" % _nums_to_str(width * 72, height * 72, 0, 0) # write the figure print >> fh, self._pswriter.getvalue() # write the trailer #print >>fh, "grestore" print >> fh, "end" print >> fh, "showpage" if not isEPSF: print >> fh, "%%EOF" fh.close() if rcParams['ps.usedistiller'] == 'ghostscript': gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox) elif rcParams['ps.usedistiller'] == 'xpdf': xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox) if passed_in_file_object: fh = file(tmpfile) print >> outfile, fh.read() else: shutil.move(tmpfile, outfile)
def get_glyphs_tex(self, prop, s, glyph_map=None, return_new_glyphs_only=False): """ convert the string *s* to vertices and codes using matplotlib's usetex mode. """ # codes are modstly borrowed from pdf backend. texmanager = self.get_texmanager() if self.tex_font_map is None: self.tex_font_map = dviread.PsfontsMap(dviread.find_tex_file('pdftex.map')) if self._adobe_standard_encoding is None: self._adobe_standard_encoding = self._get_adobe_standard_encoding() fontsize = prop.get_size_in_points() if hasattr(texmanager, "get_dvi"): # dvifilelike = texmanager.get_dvi(s, self.FONT_SCALE) dvi = dviread.DviFromFileLike(dvifilelike, self.DPI) else: dvifile = texmanager.make_dvi(s, self.FONT_SCALE) dvi = dviread.Dvi(dvifile, self.DPI) try: page = next(iter(dvi)) finally: dvi.close() if glyph_map is None: glyph_map = dict() if return_new_glyphs_only: glyph_map_new = dict() else: glyph_map_new = glyph_map glyph_ids, xpositions, ypositions, sizes = [], [], [], [] # Gather font information and do some setup for combining # characters into strings. #oldfont, seq = None, [] for x1, y1, dvifont, glyph, width in page.text: font_and_encoding = self._ps_fontd.get(dvifont.texname) font_bunch = self.tex_font_map[dvifont.texname] if font_and_encoding is None: font = FT2Font(str(font_bunch.filename)) for charmap_name, charmap_code in [("ADOBE_CUSTOM", 1094992451), ("ADOBE_STANDARD", 1094995778)]: try: font.select_charmap(charmap_code) except ValueError: pass else: break else: charmap_name = "" warnings.warn("No supported encoding in font (%s)." % font_bunch.filename) if charmap_name == "ADOBE_STANDARD" and font_bunch.encoding: enc0 = dviread.Encoding(font_bunch.encoding) enc = dict([(i, self._adobe_standard_encoding.get(c, None)) \ for i, c in enumerate(enc0.encoding)]) else: enc = dict() self._ps_fontd[dvifont.texname] = font, enc else: font, enc = font_and_encoding ft2font_flag = LOAD_TARGET_LIGHT char_id = self._get_char_id_ps(font, glyph) if not char_id in glyph_map: font.clear() font.set_size(self.FONT_SCALE, self.DPI) if enc: charcode = enc.get(glyph, None) else: charcode = glyph if charcode: glyph0 = font.load_char(charcode, flags=ft2font_flag) else: warnings.warn("The glyph (%d) of font (%s) cannot be converted with the encoding. Glyph may be wrong" % (glyph, font_bunch.filename)) glyph0 = font.load_char(glyph, flags=ft2font_flag) glyph_map_new[char_id] = self.glyph_to_path(font) glyph_ids.append(char_id) xpositions.append(x1) ypositions.append(y1) sizes.append(dvifont.size/self.FONT_SCALE) myrects = [] for ox, oy, h, w in page.boxes: vert1=[(ox, oy), (ox+w, oy), (ox+w, oy+h), (ox, oy+h), (ox, oy), (0,0)] code1 = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY] myrects.append((vert1, code1)) return zip(glyph_ids, xpositions, ypositions, sizes), \ glyph_map_new, myrects