Esempio n. 1
0
    def _output(self):
        """
        Output the text and boxes belonging to the most recent page.
        page = dvi._output()
        """
        minx, miny, maxx, maxy = np.inf, np.inf, -np.inf, -np.inf
        maxy_pure = -np.inf
        for elt in self.text + self.boxes:
            if len(elt) == 4:   # box
                x,y,h,w = elt
                e = 0           # zero depth
            else:               # glyph
                x,y,font,g,w = elt
                h,e = font._height_depth_of(g)
            minx = min(minx, x)
            miny = min(miny, y - h)
            maxx = max(maxx, x + w)
            maxy = max(maxy, y + e)
            maxy_pure = max(maxy_pure, y)

        if self.dpi is None:
            # special case for ease of debugging: output raw dvi coordinates
            return mpl_cbook.Bunch(text=self.text, boxes=self.boxes,
                                   width=maxx-minx, height=maxy_pure-miny,
                                   descent=maxy-maxy_pure)

        d = self.dpi / (72.27 * 2**16) # from TeX's "scaled points" to dpi units
        text =  [ ((x-minx)*d, (maxy-y)*d, f, g, w*d)
                  for (x,y,f,g,w) in self.text ]
        boxes = [ ((x-minx)*d, (maxy-y)*d, h*d, w*d) for (x,y,h,w) in self.boxes ]

        return mpl_cbook.Bunch(text=text, boxes=boxes,
                               width=(maxx-minx)*d,
                               height=(maxy_pure-miny)*d,
                               descent=(maxy-maxy_pure)*d)
Esempio n. 2
0
    def _register(self, words):
        """Register a font described by "words".

        The format is, AFAIK: texname fontname [effects and filenames]
        Effects are PostScript snippets like ".177 SlantFont",
        filenames begin with one or two less-than signs. A filename
        ending in enc is an encoding file, other filenames are font
        files. This can be overridden with a left bracket: <[foobar
        indicates an encoding file named foobar.

        There is some difference between <foo.pfb and <<bar.pfb in
        subsetting, but I have no example of << in my TeX installation.
        """
        texname, psname = words[:2]
        effects, encoding, filename = [], None, None
        for word in words[2:]:
            if not word.startswith('<'):
                effects.append(word)
            else:
                word = word.lstrip('<')
                if word.startswith('['):
                    assert encoding is None
                    encoding = word[1:]
                elif word.endswith('.enc'):
                    assert encoding is None
                    encoding = word
                else:
                    assert filename is None
                    filename = word
        self._font[texname] = mpl_cbook.Bunch(texname=texname,
                                              psname=psname,
                                              effects=effects,
                                              encoding=encoding,
                                              filename=filename)
Esempio n. 3
0
    def _register(self, words):
        """Register a font described by "words".

        The format is, AFAIK: texname fontname [effects and filenames]
        Effects are PostScript snippets like ".177 SlantFont",
        filenames begin with one or two less-than signs. A filename
        ending in enc is an encoding file, other filenames are font
        files. This can be overridden with a left bracket: <[foobar
        indicates an encoding file named foobar.

        There is some difference between <foo.pfb and <<bar.pfb in
        subsetting, but I have no example of << in my TeX installation.
        """

        # If the map file specifies multiple encodings for a font, we
        # follow pdfTeX in choosing the last one specified. Such
        # entries are probably mistakes but they have occurred.
        # http://tex.stackexchange.com/questions/10826/
        # http://article.gmane.org/gmane.comp.tex.pdftex/4914

        texname, psname = words[:2]
        effects, encoding, filename = '', None, None
        for word in words[2:]:
            if not word.startswith('<'):
                effects = word
            else:
                word = word.lstrip('<')
                if word.startswith('[') or word.endswith('.enc'):
                    if encoding is not None:
                        matplotlib.verbose.report(
                            'Multiple encodings for %s = %s' %
                            (texname, psname), 'debug')
                    if word.startswith('['):
                        encoding = word[1:]
                    else:
                        encoding = word
                else:
                    assert filename is None
                    filename = word

        eff = effects.split()
        effects = {}
        try:
            effects['slant'] = float(eff[eff.index('SlantFont') - 1])
        except ValueError:
            pass
        try:
            effects['extend'] = float(eff[eff.index('ExtendFont') - 1])
        except ValueError:
            pass

        self._font[texname] = mpl_cbook.Bunch(texname=texname,
                                              psname=psname,
                                              effects=effects,
                                              encoding=encoding,
                                              filename=filename)
Esempio n. 4
0
    def _register(self, words):
        """Register a font described by "words".

        The format is, AFAIK: texname fontname [effects and filenames]
        Effects are PostScript snippets like ".177 SlantFont",
        filenames begin with one or two less-than signs. A filename
        ending in enc is an encoding file, other filenames are font
        files. This can be overridden with a left bracket: <[foobar
        indicates an encoding file named foobar.

        There is some difference between <foo.pfb and <<bar.pfb in
        subsetting, but I have no example of << in my TeX installation.
        """
        texname, psname = words[:2]
        effects, encodings, filename = '', [], None
        for word in words[2:]:
            if not word.startswith('<'):
                effects = word
            else:
                word = word.lstrip('<')
                if word.startswith('['):
                    encodings.append(word[1:])
                elif word.endswith('.enc'):
                    encodings.append(word)
                else:
                    assert filename is None
                    filename = word

        if len(encodings) > 1:
            # TODO this is a stopgap workaround, need to handle this correctly
            matplotlib.verbose.report(
                'Multiple encodings for %s = %s, skipping' % (texname, psname),
                'debug')
            return
        elif len(encodings) == 1:
            encoding, = encodings
        else:
            encoding = None

        eff = effects.split()
        effects = {}
        try:
            effects['slant'] = float(eff[eff.index('SlantFont') - 1])
        except ValueError:
            pass
        try:
            effects['extend'] = float(eff[eff.index('ExtendFont') - 1])
        except ValueError:
            pass

        self._font[texname] = mpl_cbook.Bunch(texname=texname,
                                              psname=psname,
                                              effects=effects,
                                              encoding=encoding,
                                              filename=filename)
Esempio n. 5
0
def make_test_image_filenames(name, test_file):
    """
    Create filenames for testing

    Parameters
    ----------
    name : str
        An identifier for the specific test. This will make-up
        part of the filenames.
    test_file : str
        Full path of the test file. This will determine the
        directory structure

    Returns
    -------
    out : Bunch
        Object with 3 attributes to store the generated filenames

            - result
            - baseline
            - expected

        `result`, is the filename for the image generated by the test.
        `baseline`, is the filename for the baseline image to which
        the result will be compared.
        `expected`, is the filename to the copy of the baseline that
        will be stored in the same directory as the result image.
        Creating a copy make comparison easier.
    """
    if '.png' not in name:
        name = name + '.png'

    basedir = os.path.abspath(os.path.dirname(test_file))
    basename = os.path.basename(test_file)
    subdir = os.path.splitext(basename)[0]

    baseline_dir = os.path.join(basedir, 'baseline_images', subdir)
    result_dir = os.path.abspath(os.path.join('result_images', subdir))

    if not os.path.exists(result_dir):
        cbook.mkdirs(result_dir)

    base, ext = os.path.splitext(name)
    expected_name = '{}-{}{}'.format(base, 'expected', ext)

    filenames = cbook.Bunch(baseline=os.path.join(baseline_dir, name),
                            result=os.path.join(result_dir, name),
                            expected=os.path.join(result_dir, expected_name))
    return filenames
Esempio n. 6
0
    def start_pan(self, x, y, button):
        angle = self._r_label1_position.to_values()[4] / 180.0 * npy.pi
        mode = ''
        if button == 1:
            epsilon = npy.pi / 45.0
            t, r = self.transData.inverted().transform_point((x, y))
            if t >= angle - epsilon and t <= angle + epsilon:
                mode = 'drag_r_labels'
        elif button == 3:
            mode = 'zoom'

        self._pan_start = cbook.Bunch(
            rmax=self.get_rmax(),
            trans=self.transData.frozen(),
            trans_inverse=self.transData.inverted().frozen(),
            r_label_angle=self._r_label1_position.to_values()[4],
            x=x,
            y=y,
            mode=mode)
Esempio n. 7
0
# http://mirrors.ctan.org/systems/knuth/dist/texware/dvitype.web
# http://texdoc.net/texmf-dist/doc/generic/knuth/texware/dvitype.pdf
#
# The file consists of a preamble, some number of pages, a postamble,
# and a finale. Different opcodes are allowed in different contexts,
# so the Dvi object has a parser state:
#
#   pre:       expecting the preamble
#   outer:     between pages (followed by a page or the postamble,
#              also e.g. font definitions are allowed)
#   page:      processing a page
#   post_post: state after the postamble (our current implementation
#              just stops reading)
#   finale:    the finale (unimplemented in our current implementation)

_dvistate = mpl_cbook.Bunch(pre=0, outer=1, inpage=2, post_post=3, finale=4)

# The marks on a page consist of text and boxes. A page also has dimensions.
Page = namedtuple('Page', 'text boxes height width descent')
Text = namedtuple('Text', 'x y font glyph width')
Box = namedtuple('Box', 'x y height width')

# Opcode argument parsing
#
# Each of the following functions takes a Dvi object and delta,
# which is the difference between the opcode and the minimum opcode
# with the same meaning. Dvi opcodes often encode the number of
# argument bytes in this delta.


def _arg_raw(dvi, delta):
Esempio n. 8
0
 def _finalize_packet(self):
     self._chars[self._packet_char] = mpl_cbook.Bunch(
         text=self.text, boxes=self.boxes, width=self._packet_width)
     self.state = _dvistate.outer