def _get_ps_font_and_encoding(texname): tex_font_map = dviread.PsfontsMap(dviread.find_tex_file('pdftex.map')) font_bunch = tex_font_map[texname] if font_bunch.filename is None: raise ValueError(("No usable font file found for %s (%s). " "The font may lack a Type-1 version.") % (font_bunch.psname, texname)) font = get_font(font_bunch.filename) for charmap_name, charmap_code in [("ADOBE_CUSTOM", 1094992451), ("ADOBE_STANDARD", 1094995778)]: try: font.select_charmap(charmap_code) except (ValueError, RuntimeError): 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 = { i: _get_adobe_standard_encoding().get(c, None) for i, c in enumerate(enc0.encoding) } else: enc = {} return font, enc
def test_PsfontsMap(monkeypatch): monkeypatch.setattr(dr, '_find_tex_file', lambda x: x) filename = str(Path(__file__).parent / 'baseline_images/dviread/test.map') fontmap = dr.PsfontsMap(filename) # Check all properties of a few fonts for n in [1, 2, 3, 4, 5]: key = b'TeXfont%d' % n entry = fontmap[key] assert entry.texname == key assert entry.psname == b'PSfont%d' % n if n not in [3, 5]: assert entry.encoding == b'font%d.enc' % n elif n == 3: assert entry.encoding == b'enc3.foo' # We don't care about the encoding of TeXfont5, which specifies # multiple encodings. if n not in [1, 5]: assert entry.filename == b'font%d.pfa' % n else: assert entry.filename == b'font%d.pfb' % n if n == 4: assert entry.effects == {'slant': -0.1, 'extend': 1.2} else: assert entry.effects == {} # Some special cases entry = fontmap[b'TeXfont6'] assert entry.filename is None assert entry.encoding is None entry = fontmap[b'TeXfont7'] assert entry.filename is None assert entry.encoding == b'font7.enc' entry = fontmap[b'TeXfont8'] assert entry.filename == b'font8.pfb' assert entry.encoding is None entry = fontmap[b'TeXfont9'] assert entry.psname == b'TeXfont9' assert entry.filename == b'/absolute/font9.pfb' # First of duplicates only. entry = fontmap[b'TeXfontA'] assert entry.psname == b'PSfontA1' # Slant/Extend only works for T1 fonts. entry = fontmap[b'TeXfontB'] assert entry.psname == b'PSfontB6' # Subsetted TrueType must have encoding. entry = fontmap[b'TeXfontC'] assert entry.psname == b'PSfontC3' # Missing font with pytest.raises(LookupError, match='no-such-font'): fontmap[b'no-such-font'] with pytest.raises(LookupError, match='%'): fontmap[b'%']
def _get_ps_font_and_encoding(texname): tex_font_map = dviread.PsfontsMap(dviread.find_tex_file('pdftex.map')) font_bunch = tex_font_map[texname] if font_bunch.filename is None: raise ValueError( f"No usable font file found for {font_bunch.psname} " f"({texname}). The font may lack a Type-1 version.") font = get_font(font_bunch.filename) if font_bunch.encoding: # If psfonts.map specifies an encoding, use it: it gives us a # mapping of glyph indices to Adobe glyph names; use it to convert # dvi indices to glyph names and use the FreeType-synthesized # unicode charmap to convert glyph names to glyph indices (with # FT_Get_Name_Index/get_name_index), and load the glyph using # FT_Load_Glyph/load_glyph. (That charmap has a coverage at least # as good as, and possibly better than, the native charmaps.) enc = dviread._parse_enc(font_bunch.encoding) else: # If psfonts.map specifies no encoding, the indices directly # map to the font's "native" charmap; so don't use the # FreeType-synthesized charmap but the native ones (we can't # directly identify it but it's typically an Adobe charmap), and # directly load the dvi glyph indices using FT_Load_Char/load_char. for charmap_name, charmap_code in [ ("ADOBE_CUSTOM", 1094992451), ("ADOBE_STANDARD", 1094995778), ]: try: font.select_charmap(charmap_code) except (ValueError, RuntimeError): pass else: break else: charmap_name = "" _log.warning("No supported encoding in font (%s).", font_bunch.filename) enc = None return font, enc
def test_PsfontsMap(monkeypatch): monkeypatch.setattr(dr, 'find_tex_file', lambda x: x) filename = os.path.join(os.path.dirname(__file__), 'baseline_images', 'dviread', 'test.map') fontmap = dr.PsfontsMap(filename) # Check all properties of a few fonts for n in [1, 2, 3, 4, 5]: key = ('TeXfont%d' % n).encode('ascii') entry = fontmap[key] assert entry.texname == key assert entry.psname == ('PSfont%d' % n).encode('ascii') if n not in [3, 5]: assert entry.encoding == ('font%d.enc' % n).encode('ascii') elif n == 3: assert entry.encoding == b'enc3.foo' # We don't care about the encoding of TeXfont5, which specifies # multiple encodings. if n not in [1, 5]: assert entry.filename == ('font%d.pfa' % n).encode('ascii') else: assert entry.filename == ('font%d.pfb' % n).encode('ascii') if n == 4: assert entry.effects == {'slant': -0.1, 'extend': 2.2} else: assert entry.effects == {} # Some special cases entry = fontmap[b'TeXfont6'] assert entry.filename is None assert entry.encoding is None entry = fontmap[b'TeXfont7'] assert entry.filename is None assert entry.encoding == b'font7.enc' entry = fontmap[b'TeXfont8'] assert entry.filename == b'font8.pfb' assert entry.encoding is None entry = fontmap[b'TeXfont9'] assert entry.filename == b'/absolute/font9.pfb' # Missing font with pytest.raises(KeyError) as exc: fontmap[b'no-such-font'] assert 'no-such-font' in str(exc.value)
def test_PsfontsMap(): filename = os.path.join( os.path.dirname(__file__), 'baseline_images', 'dviread', 'test.map') fontmap = dr.PsfontsMap(filename) # Check all properties of a few fonts for n in [1, 2, 3, 4, 5]: key = 'TeXfont%d' % n entry = fontmap[key] assert_equal(entry.texname, key) assert_equal(entry.psname, 'PSfont%d' % n) if n not in [3, 5]: assert_equal(entry.encoding, 'font%d.enc' % n) elif n == 3: assert_equal(entry.encoding, 'enc3.foo') # We don't care about the encoding of TeXfont5, which specifies # multiple encodings. if n not in [1, 5]: assert_equal(entry.filename, 'font%d.pfa' % n) else: assert_equal(entry.filename, 'font%d.pfb' % n) if n == 4: assert_equal(entry.effects, {'slant': -0.1, 'extend': 2.2}) else: assert_equal(entry.effects, {}) # Some special cases entry = fontmap['TeXfont6'] assert_equal(entry.filename, None) assert_equal(entry.encoding, None) entry = fontmap['TeXfont7'] assert_equal(entry.filename, None) assert_equal(entry.encoding, 'font7.enc') entry = fontmap['TeXfont8'] assert_equal(entry.filename, 'font8.pfb') assert_equal(entry.encoding, None) entry = fontmap['TeXfont9'] assert_equal(entry.filename, '/absolute/font9.pfb')
def _get_tex_font_map(): return dviread.PsfontsMap(dviread.find_tex_file("pdftex.map"))
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 tex_font_map(self): return dviread.PsfontsMap(dviread.find_tex_file('pdftex.map'))
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