Esempio n. 1
0
    def processNextJob(self):
        """Take a job from the queue and process it.

        emits renderfinished(jobid, img, painthelper)
        when done, if job has not been superseded
        """

        self.mutex.lock()
        jobid, helper = self.latestjobs[-1]
        del self.latestjobs[-1]
        lastadded = self.latestaddedjob
        self.mutex.unlock()

        # don't process jobs which have been superseded
        if lastadded == jobid:
            img = qt4.QImage(helper.pagesize[0], helper.pagesize[1],
                             qt4.QImage.Format_ARGB32_Premultiplied)
            img.fill(setting.settingdb.color('page').rgb())

            painter = qt4.QPainter(img)
            aa = self.plotwindow.antialias
            painter.setRenderHint(qt4.QPainter.Antialiasing, aa)
            painter.setRenderHint(qt4.QPainter.TextAntialiasing, aa)
            helper.renderToPainter(painter)
            painter.end()

            self.mutex.lock()
            # just throw away result if it older than the latest one
            if jobid > self.latestdrawnjob:
                self.emit(qt4.SIGNAL("renderfinished"), jobid, img, helper)
                self.latestdrawnjob = jobid
            self.mutex.unlock()

        # tell any listeners that a job has been processed
        self.plotwindow.emit(qt4.SIGNAL("queuechange"), -1)
Esempio n. 2
0
    def painter(self, widget, bounds, clip=None):
        """Return a painter for use when drawing the widget.
        widget: widget object
        bounds: tuple (x1, y1, x2, y2) of widget bounds
        clip: another tuple, if set clips drawing to this rectangle
        """
        s = self.states[widget] = DrawState(widget, bounds, clip, self)
        if widget.parent is None:
            self.rootstate = s
        else:
            self.states[widget.parent].children.append(s)

        if self.directpaint:
            # only paint to one output painter
            p = self.directpaint
            if self.directpainting:
                p.restore()
            self.directpainting = True
            p.save()
        else:
            # save to multiple recorded layers
            p = qt4.QPainter(s.record)

        p.scaling = self.scaling
        p.pixperpt = self.pixperpt
        p.pagesize = self.pagesize
        p.maxsize = max(*self.pagesize)
        p.dpi = self.dpi[1]

        if clip:
            p.setClipRect(clip)

        return p
Esempio n. 3
0
class _MmlRenderer(_Renderer):
    """MathML renderer."""
    def _initText(self, text):
        """Setup MML document and draw it in recording paint device."""

        self.error = ''
        self.size = qt4.QSize(1, 1)
        if not mmlsupport:
            self.mmldoc = None
            self.error = 'Error: MathML support not built\n'
            return

        self.mmldoc = doc = qtmml.QtMmlDocument()
        try:
            self.mmldoc.setContent(text)
        except ValueError, e:
            self.mmldoc = None
            self.error = ('Error interpreting MathML: %s\n' % unicode(e))
            return

        # this is pretty horrible :-(

        # We write the mathmml document to a RecordPaintDevice device
        # at the same DPI as the screen, because the MML code breaks
        # for other DPIs. We then repaint the output to the real
        # device, scaling to make the size correct.

        screendev = qt4.QApplication.desktop()
        self.record = recordpaint.RecordPaintDevice(1024, 1024,
                                                    screendev.logicalDpiX(),
                                                    screendev.logicalDpiY())

        rpaint = qt4.QPainter(self.record)
        # painting code relies on these attributes of the painter
        rpaint.pixperpt = screendev.logicalDpiY() / 72.
        rpaint.scaling = 1.0

        # Upscale any drawing by this factor, then scale back when
        # drawing. We have to do this to get consistent output at
        # different zoom factors (I hate this code).
        upscale = 5.

        doc.setFontName(qtmml.QtMmlWidget.NormalFont, self.font.family())

        ptsize = self.font.pointSizeF()
        if ptsize < 0:
            ptsize = self.font.pixelSize() / self.painter.pixperpt
        ptsize /= self.painter.scaling

        doc.setBaseFontPointSize(ptsize * upscale)

        # the output will be painted finally scaled
        self.drawscale = (self.painter.scaling * self.painter.dpi /
                          screendev.logicalDpiY() / upscale)
        self.size = doc.size() * self.drawscale

        doc.paint(rpaint, qt4.QPoint(0, 0))
        rpaint.end()
Esempio n. 4
0
    def exportPIC(self):
        """Export document as Qt PIC"""

        pic = qt4.QPicture()
        painter = qt4.QPainter(pic)

        dpi = (pic.logicalDpiX(), pic.logicalDpiY())
        size = self.doc.pageSize(self.pagenumber, dpi=dpi)
        self.renderPage(size, dpi, painter)
        pic.save(self.filename)
Esempio n. 5
0
    def exportEMF(self):
        """Export document as EMF."""

        dpi = 90.
        size = self.doc.pageSize(self.pagenumber,
                                 dpi=(dpi, dpi),
                                 integer=False)

        paintdev = emf_export.EMFPaintDevice(size[0] / dpi,
                                             size[1] / dpi,
                                             dpi=dpi)
        painter = qt4.QPainter(paintdev)
        self.renderPage(size, (dpi, dpi), painter)
        paintdev.paintEngine().saveFile(self.filename)
Esempio n. 6
0
    def exportSelfTest(self):
        """Export document for testing"""

        dpi = svg_export.dpi * 1.
        size = width, height = self.doc.pageSize(self.pagenumber,
                                                 dpi=(dpi, dpi),
                                                 integer=False)

        f = open(self.filename, 'w')
        paintdev = selftest_export.SelfTestPaintDevice(f, width / dpi,
                                                       height / dpi)
        painter = qt4.QPainter(paintdev)
        self.renderPage(size, (dpi, dpi), painter)
        f.close()
Esempio n. 7
0
    def exportSVG(self):
        """Export document as SVG"""

        if qt4.PYQT_VERSION >= 0x40600:
            # custom paint devices don't work in old PyQt versions

            dpi = svg_export.dpi * 1.
            size = self.doc.pageSize(self.pagenumber,
                                     dpi=(dpi, dpi),
                                     integer=False)
            f = open(self.filename, 'w')
            paintdev = svg_export.SVGPaintDevice(
                f,
                size[0] / dpi,
                size[1] / dpi,
                writetextastext=self.svgtextastext)
            painter = qt4.QPainter(paintdev)
            self.renderPage(size, (dpi, dpi), painter)
            f.close()
        else:
            # use built-in svg generation, which doesn't work very well
            # (no clipping, font size problems)
            import PyQt4.QtSvg

            dpi = 90.
            size = self.doc.pageSize(self.pagenumber,
                                     dpi=(dpi, dpi),
                                     integer=False)

            # actually paint the image
            gen = PyQt4.QtSvg.QSvgGenerator()
            gen.setFileName(self.filename)
            gen.setResolution(dpi)
            gen.setSize(qt4.QSize(int(size[0]), int(size[1])))
            painter = qt4.QPainter(gen)
            self.renderPage(size, (dpi, dpi), painter)
Esempio n. 8
0
    def getPreviewPixmap(self, ds):
        """Get a preview pixmap for a dataset."""
        size = (140, 70)
        if ds.dimensions != 1 or ds.datatype != "numeric":
            return None

        pixmap = qt4.QPixmap(*size)
        pixmap.fill(qt4.Qt.transparent)
        p = qt4.QPainter(pixmap)
        p.setRenderHint(qt4.QPainter.Antialiasing)

        # calculate data points
        try:
            if len(ds.data) < size[1]:
                y = ds.data
            else:
                intvl = len(ds.data) / size[1] + 1
                y = ds.data[::intvl]
            x = N.arange(len(y))

            # plot data points on image
            minval, maxval = N.nanmin(y), N.nanmax(y)
            y = (y - minval) / (maxval - minval) * size[1]
            finite = N.isfinite(y)
            x, y = x[finite], y[finite]
            x = x * (1. / len(x)) * size[0]

            poly = qt4.QPolygonF()
            utils.addNumpyToPolygonF(poly, x, size[1] - y)
            p.setPen(qt4.QPen(qt4.Qt.blue))
            p.drawPolyline(poly)

            # draw x axis if span 0
            p.setPen(qt4.QPen(qt4.Qt.black))
            if minval <= 0 and maxval > 0:
                y0 = size[1] - (0 - minval) / (maxval - minval) * size[1]
                p.drawLine(x[0], y0, x[-1], y0)
            else:
                p.drawLine(x[0], size[1], x[-1], size[1])
            p.drawLine(x[0], 0, x[0], size[1])

        except (ValueError, ZeroDivisionError):
            # zero sized array after filtering or min == max, so return None
            p.end()
            return None

        p.end()
        return pixmap
Esempio n. 9
0
    def exportBitmap(self, format):
        """Export to a bitmap format."""

        # get size for bitmap's dpi
        dpi = self.bitmapdpi
        size = self.doc.pageSize(self.pagenumber, dpi=(dpi, dpi))

        # create real output image
        backqcolor = utils.extendedColorToQColor(self.backcolor)
        if format == '.png':
            # transparent output
            image = qt4.QImage(size[0], size[1],
                               qt4.QImage.Format_ARGB32_Premultiplied)
        else:
            # non transparent output
            image = qt4.QImage(size[0], size[1], qt4.QImage.Format_RGB32)
            backqcolor.setAlpha(255)

        image.setDotsPerMeterX(dpi * m_inch)
        image.setDotsPerMeterY(dpi * m_inch)
        if backqcolor.alpha() == 0:
            image.fill(qt4.qRgba(0, 0, 0, 0))
        else:
            image.fill(backqcolor.rgb())

        # paint to the image
        painter = qt4.QPainter(image)
        painter.setRenderHint(qt4.QPainter.Antialiasing, self.antialias)
        painter.setRenderHint(qt4.QPainter.TextAntialiasing, self.antialias)
        self.renderPage(size, (dpi, dpi), painter)

        # write image to disk
        writer = qt4.QImageWriter()
        # format below takes extension without dot
        writer.setFormat(qt4.QByteArray(format[1:]))
        writer.setFileName(self.filename)

        if format == 'png':
            # min quality for png as it makes no difference to output
            # and makes file size smaller
            writer.setQuality(0)
        else:
            writer.setQuality(self.quality)

        writer.write(image)
Esempio n. 10
0
        def rendernextstate(state):
            """Recursively draw painter.

            Checks whether drawing a widgetchanges the small image
            around the point given.
            """

            pixmap = qt4.QPixmap(origpix)
            painter = qt4.QPainter(pixmap)
            painter.setRenderHint(qt4.QPainter.Antialiasing, antialias)
            painter.setRenderHint(qt4.QPainter.TextAntialiasing, antialias)
            # this makes the small image draw from x-box->x+box, y-box->y+box
            # translate would get overriden by coordinate system playback
            painter.setWindow(x-box,y-box,box*2+1,box*2+1)
            state.record.play(painter)
            painter.end()
            newimg = pixmap.toImage()

            if newimg != origimg:
                lastwidget[0] = state.widget

            for child in state.children:
                rendernextstate(child)
Esempio n. 11
0
def makeSplashLogo():
    '''Make a splash screen logo.'''
    border = 16
    xw, yw = 520, 240
    pix = qt4.QPixmap(xw, yw)
    pix.fill()
    p = qt4.QPainter(pix)

    # draw logo on pixmap
    logo = utils.getPixmap('logo.png')
    p.drawPixmap(xw / 2 - logo.width() / 2, border, logo)

    # add copyright text
    doc = qt4.QTextDocument()
    doc.setPageSize(qt4.QSizeF(xw, yw - 3 * border - logo.height()))
    f = qt4.qApp.font()
    f.setPointSize(14)
    doc.setDefaultFont(f)
    doc.setDefaultTextOption(qt4.QTextOption(qt4.Qt.AlignCenter))
    doc.setHtml(splashcopyr % utils.version())
    p.translate(0, 2 * border + logo.height())
    doc.drawContents(p)
    p.end()
    return pix
Esempio n. 12
0
    def printTo(self, printer, pages, scaling=1., dpi=None, antialias=False):
        """Print onto printing device."""

        dpi = (printer.logicalDpiX(), printer.logicalDpiY())
        painter = qt4.QPainter(printer)
        if antialias:
            painter.setRenderHint(qt4.QPainter.Antialiasing, True)
            painter.setRenderHint(qt4.QPainter.TextAntialiasing, True)

        # This all assumes that only pages can go into the root widget
        num = len(pages)
        for count, page in enumerate(pages):
            size = self.pageSize(page, dpi=dpi)
            helper = painthelper.PaintHelper(size,
                                             dpi=dpi,
                                             directpaint=painter)
            self.paintTo(helper, page)
            painter.restore()

            # start new pages between each page
            if count < num - 1:
                printer.newPage()

        painter.end()
Esempio n. 13
0
    def exportPS(self, ext):
        """Export to EPS or PDF format."""

        printer = qt4.QPrinter()
        printer.setFullPage(True)

        # set printer parameters
        printer.setColorMode(
            (qt4.QPrinter.GrayScale, qt4.QPrinter.Color)[self.color])

        if ext == '.pdf':
            fmt = qt4.QPrinter.PdfFormat
        else:
            fmt = qt4.QPrinter.PostScriptFormat
        printer.setOutputFormat(fmt)
        printer.setOutputFileName(self.filename)
        printer.setCreator('Veusz %s' % utils.version())
        printer.setResolution(self.pdfdpi)

        # setup for printing
        printer.newPage()
        painter = qt4.QPainter(printer)

        # write to printer with correct dpi
        dpi = (printer.logicalDpiX(), printer.logicalDpiY())
        width, height = size = self.doc.pageSize(self.pagenumber, dpi=dpi)
        self.renderPage(size, dpi, painter)

        # fixup eps/pdf file - yuck HACK! - hope qt gets fixed
        # this makes the bounding box correct
        # copy output to a temporary file
        tmpfile = "%s.tmp.%i" % (self.filename, random.randint(0, 1000000))
        fout = open(tmpfile, 'wb')
        fin = open(self.filename, 'rb')

        if ext == '.eps':
            # adjust bounding box
            for line in fin:
                if line[:14] == '%%BoundingBox:':
                    # replace bounding box line by calculated one
                    parts = line.split()
                    widthfactor = float(parts[3]) / printer.width()
                    origheight = float(parts[4])
                    line = "%s %i %i %i %i\n" % (
                        parts[0], 0,
                        int(math.floor(origheight - widthfactor * height)),
                        int(math.ceil(
                            widthfactor * width)), int(math.ceil(origheight)))
                fout.write(line)

        elif ext == '.pdf':
            # change pdf bounding box and correct pdf index
            text = fin.read()
            text = utils.scalePDFMediaBox(text, printer.width(), width, height)
            text = utils.fixupPDFIndices(text)
            fout.write(text)

        fout.close()
        fin.close()
        os.remove(self.filename)
        os.rename(tmpfile, self.filename)