Exemplo n.º 1
0
    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
Exemplo n.º 2
0
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'%']
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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')
Exemplo n.º 6
0
def _get_tex_font_map():
    return dviread.PsfontsMap(dviread.find_tex_file("pdftex.map"))
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
 def tex_font_map(self):
     return dviread.PsfontsMap(dviread.find_tex_file('pdftex.map'))
Exemplo n.º 9
0
    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