Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
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 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)
Ejemplo n.º 4
0
 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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
 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)
Ejemplo n.º 9
0
 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)
Ejemplo n.º 10
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
Ejemplo n.º 11
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()

        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)
Ejemplo n.º 12
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
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
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 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)