def get_text_width_height_descent(self, tex, fontsize, renderer=None): """Return width, height and descent of the text.""" if tex.strip() == '': return 0, 0, 0 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1 if rcParams['text.latex.preview']: # use preview.sty basefile = self.get_basefile(tex, fontsize) baselinefile = '%s.baseline' % basefile if not os.path.exists(baselinefile): dvifile = self.make_dvi_preview(tex, fontsize) with open(baselinefile) as fh: l = fh.read().split() height, depth, width = [float(l1) * dpi_fraction for l1 in l] return width, height + depth, depth else: # use dviread. dvifile = self.make_dvi(tex, fontsize) with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi: page, = dvi # A total height (including the descent) needs to be returned. return page.width, page.height + page.descent, page.descent
def get_text_width_height_descent(self, tex, fontsize, renderer=None): """ return width, heigth and descent of the text. """ if tex.strip() == '': return 0, 0, 0 if renderer: dpi_fraction = renderer.points_to_pixels(1.) else: dpi_fraction = 1. if rcParams['text.latex.preview']: # use preview.sty basefile = self.get_basefile(tex, fontsize) baselinefile = '%s.baseline' % basefile if DEBUG or not os.path.exists(baselinefile): dvifile = self.make_dvi_preview(tex, fontsize) with open(baselinefile) as fh: l = fh.read().split() height, depth, width = [float(l1) * dpi_fraction for l1 in l] return width, height + depth, depth else: # use dviread. It sometimes returns a wrong descent. dvifile = self.make_dvi(tex, fontsize) dvi = dviread.Dvi(dvifile, 72 * dpi_fraction) try: page = next(iter(dvi)) finally: dvi.close() # A total height (including the descent) needs to be returned. return page.width, page.height + page.descent, page.descent
def get_glyphs_tex(self, prop, s, glyph_map=None, return_new_glyphs_only=False): """Convert the string *s* to vertices and codes using usetex mode.""" # Mostly borrowed from pdf backend. dvifile = self.get_texmanager().make_dvi(s, self.FONT_SCALE) with dviread.Dvi(dvifile, self.DPI) as dvi: page, = dvi if glyph_map is None: glyph_map = OrderedDict() if return_new_glyphs_only: glyph_map_new = OrderedDict() else: glyph_map_new = glyph_map glyph_ids, xpositions, ypositions, sizes = [], [], [], [] # Gather font information and do some setup for combining # characters into strings. for x1, y1, dvifont, glyph, width in page.text: font, enc = self._get_ps_font_and_encoding(dvifont.texname) char_id = self._get_char_id_ps(font, glyph) if char_id not in glyph_map: font.clear() font.set_size(self.FONT_SCALE, self.DPI) # See comments in _get_ps_font_and_encoding. if enc is not None: index = font.get_name_index(enc[glyph]) font.load_glyph(index, flags=LOAD_TARGET_LIGHT) else: font.load_char(glyph, flags=LOAD_TARGET_LIGHT) glyph_map_new[char_id] = font.get_path() 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 (list(zip(glyph_ids, xpositions, ypositions, sizes)), glyph_map_new, myrects)
def get_text_width_height_descent(self, tex, fontsize, renderer=None): """Return width, height and descent of the text.""" if tex.strip() == '': return 0, 0, 0 dvifile = self.make_dvi(tex, fontsize) dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1 with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi: page, = dvi # A total height (including the descent) needs to be returned. return page.width, page.height + page.descent, page.descent
def test_dviread(): dir = os.path.join(os.path.dirname(__file__), 'baseline_images', 'dviread') with open(os.path.join(dir, 'test.json')) as f: correct = json.load(f) with dr.Dvi(os.path.join(dir, 'test.dvi'), None) as dvi: data = [{'text': [[t.x, t.y, six.unichr(t.glyph), six.text_type(t.font.texname), round(t.font.size, 2)] for t in page.text], 'boxes': [[b.x, b.y, b.height, b.width] for b in page.boxes]} for page in dvi] assert data == correct
def test_dviread(): dirpath = Path(__file__).parent / 'baseline_images/dviread' with (dirpath / 'test.json').open() as f: correct = json.load(f) with dr.Dvi(str(dirpath / 'test.dvi'), None) as dvi: data = [{'text': [[t.x, t.y, chr(t.glyph), t.font.texname.decode('ascii'), round(t.font.size, 2)] for t in page.text], 'boxes': [[b.x, b.y, b.height, b.width] for b in page.boxes]} for page in dvi] assert data == correct
def test_dviread(): dir = os.path.join(os.path.dirname(__file__), 'baseline_images', 'dviread') with open(os.path.join(dir, 'test.json')) as f: correct = json.load(f) for entry in correct: entry['text'] = [[a, b, c, d.encode('ascii'), e] for [a, b, c, d, e] in entry['text']] with dr.Dvi(os.path.join(dir, 'test.dvi'), None) as dvi: data = [{ 'text': [[t.x, t.y, chr(t.glyph), t.font.texname, round(t.font.size, 2)] for t in page.text], 'boxes': [[b.x, b.y, b.height, b.width] for b in page.boxes] } for page in dvi] assert data == correct
def draw_tex(self, gc, x, y, s, prop, angle, ismath="TeX!", mtext=None): fontsize = prop.get_size_in_points() dvifile = self.get_texmanager().make_dvi(s, fontsize) with dviread.Dvi(dvifile, self.dpi) as dvi: page = next(iter(dvi)) mb = _mplcairo.MathtextBackendCairo() for x1, y1, dvifont, glyph, width in page.text: texfont = _get_tex_font_map()[dvifont.texname] if texfont.filename is None: # Not TypeError: # :mpltest:`test_backend_svg.test_missing_psfont`. raise ValueError("No font file found for {} ({!a})".format( texfont.psname, texfont.texname)) mb._render_usetex_glyph(x1, -y1, texfont.filename, dvifont.size, glyph) for x1, y1, h, w in page.boxes: mb.render_rect_filled(x1, -y1, x1 + w, -(y1 + h)) mb._draw(self, x, y, angle)
def draw_tex(self, gc, x, y, s, prop, angle, ismath="TeX!", mtext=None): fontsize = prop.get_size_in_points() dvifile = self.get_texmanager().make_dvi(s, fontsize) with dviread.Dvi(dvifile, self.dpi) as dvi: page = next(iter(dvi)) mb = _mplcairo.MathtextBackendCairo() for text in page.text: texfont = _get_tex_font_map()[text.font.texname] if texfont.filename is None: # Not TypeError: # :mpltest:`test_backend_svg.test_missing_psfont`. raise ValueError(f"No font file found for {texfont.psname} " f"({texfont.texname!a})") mb._render_usetex_glyph(text.x, -text.y, texfont.filename, text.font.size, get_glyph_name(text) or text.glyph, texfont.effects.get("slant", 0), texfont.effects.get("extend", 1)) for x1, y1, h, w in page.boxes: mb.render_rect_filled(x1, -y1, x1 + w, -(y1 + h)) mb._draw(self, x, y, angle)
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
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() 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) with dvi: page = next(iter(dvi)) if glyph_map is None: glyph_map = OrderedDict() if return_new_glyphs_only: glyph_map_new = OrderedDict() 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, enc = self._get_ps_font_and_encoding(dvifont.texname) char_id = self._get_char_id_ps(font, glyph) if char_id not in glyph_map: font.clear() font.set_size(self.FONT_SCALE, self.DPI) if enc: charcode = enc.get(glyph, None) else: charcode = glyph ft2font_flag = LOAD_TARGET_LIGHT if charcode is not None: 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.fname)) 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 (list(zip(glyph_ids, xpositions, ypositions, sizes)), glyph_map_new, myrects)
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 get_glyphs_tex(self, prop, s, glyph_map=None, return_new_glyphs_only=False): """ Process string *s* with usetex and convert it to a (vertices, codes) pair. """ # Implementation mostly borrowed from pdf backend. dvifile = self.get_texmanager().make_dvi(s, self.FONT_SCALE) with dviread.Dvi(dvifile, self.DPI) as dvi: page, = dvi if glyph_map is None: glyph_map = OrderedDict() if return_new_glyphs_only: glyph_map_new = OrderedDict() else: glyph_map_new = glyph_map glyph_ids, xpositions, ypositions, sizes = [], [], [], [] # Gather font information and do some setup for combining # characters into strings. for x1, y1, dvifont, glyph, width in page.text: font, enc = self._get_ps_font_and_encoding(dvifont.texname) char_id = self._get_char_id_ps(font, glyph) if char_id not in glyph_map: font.clear() font.set_size(self.FONT_SCALE, self.DPI) if enc: charcode = enc.get(glyph, None) else: charcode = glyph ft2font_flag = LOAD_TARGET_LIGHT if charcode is not None: glyph0 = font.load_char(charcode, flags=ft2font_flag) else: _log.warning( "The glyph (%d) of font (%s) cannot be " "converted with the encoding. Glyph may " "be wrong.", glyph, font.fname) glyph0 = font.load_char(glyph, flags=ft2font_flag) glyph_map_new[char_id] = font.get_path() 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 (list(zip(glyph_ids, xpositions, ypositions, sizes)), glyph_map_new, myrects)
def get_glyphs_tex(self, prop, s, glyph_map=None, return_new_glyphs_only=False): """Convert the string *s* to vertices and codes using usetex mode.""" # Mostly borrowed from pdf backend. dvifile = TexManager().make_dvi(s, self.FONT_SCALE) with dviread.Dvi(dvifile, self.DPI) as dvi: page, = dvi if glyph_map is None: glyph_map = OrderedDict() if return_new_glyphs_only: glyph_map_new = OrderedDict() else: glyph_map_new = glyph_map glyph_ids, xpositions, ypositions, sizes = [], [], [], [] # Gather font information and do some setup for combining # characters into strings. for text in page.text: font = get_font(text.font_path) char_id = self._get_char_id(font, text.glyph) if char_id not in glyph_map: font.clear() font.set_size(self.FONT_SCALE, self.DPI) glyph_name_or_index = text.glyph_name_or_index if isinstance(glyph_name_or_index, str): index = font.get_name_index(glyph_name_or_index) font.load_glyph(index, flags=LOAD_TARGET_LIGHT) elif isinstance(glyph_name_or_index, int): self._select_native_charmap(font) font.load_char(glyph_name_or_index, flags=LOAD_TARGET_LIGHT) else: # Should not occur. raise TypeError(f"Glyph spec of unexpected type: " f"{glyph_name_or_index!r}") glyph_map_new[char_id] = font.get_path() glyph_ids.append(char_id) xpositions.append(text.x) ypositions.append(text.y) sizes.append(text.font_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 (list(zip(glyph_ids, xpositions, ypositions, sizes)), glyph_map_new, myrects)