示例#1
0
def utilities_fast_blur(surface, radius, algotype):
    """This is the 'official' method to access the blur algorithms. The last
	argument is an integer corresponding to the BlurType enumeration."""
    radius = int(radius)
    if radius < 1:
        return

    if algotype == BlurType.INVALID:
        return
    elif algotype == BlurType.AUTO:
        algotype = BlurType.PX_BOX
        # if radius > 6:
        # 	algotype = BlurType.PX_BOX
        # else:
        # 	algotype = BlurType.CAIRO_BOX

    w = surface.get_width()
    h = surface.get_height()
    channels = 4  # ARGB
    if radius > w - 1 or radius > h - 1:
        return

    # this code a modified version of this https://github.com/elementary/granite/blob/14e3aaa216b61f7e63762214c0b36ee97fa7c52b/lib/Drawing/BufferSurface.vala#L230
    # the main differences (aside of the language) is the poor attempt to use
    # multithreading (i'm quite sure the access to buffers are not safe at all).
    # The 2 phases of the algo have been separated to allow directional blur.
    original = cairo.ImageSurface(cairo.Format.ARGB32, w, h)
    cairo_context = cairo.Context(original)
    # cairo_context.set_operator(cairo.Operator.SOURCE)
    cairo_context.set_source_surface(surface, 0, 0)
    cairo_context.paint()
    original.flush()
    pixels = original.get_data()

    buffer0 = [None] * (w * h * channels)
    vmin = [None] * max(w, h)
    vmax = [None] * max(w, h)
    div = 2 * radius + 1
    dv = [None] * (256 * div)
    for i in range(0, len(dv)):
        dv[i] = int(i / div)

    iterations = 1
    while iterations > 0:
        iterations = iterations - 1
        time0 = datetime.now()
        print('begin fast blur, using algo n°', algotype)
        if algotype == BlurType.PX_HORIZONTAL:
            _fast_blur_1st_phase(w, h, channels, radius, pixels, buffer0, vmin,
                                 vmax, dv)
            for i in range(0, len(buffer0)):
                pixels[i] = buffer0[i]  # XXX useful?
        elif algotype == BlurType.PX_VERTICAL:
            for i in range(0, len(pixels)):
                buffer0[i] = pixels[i]  # XXX useful?
            _fast_blur_2nd_phase(w, h, channels, radius, pixels, buffer0, vmin,
                                 vmax, dv)
        elif algotype == BlurType.PX_BOX:
            _fast_blur_1st_phase(w, h, channels, radius, pixels, buffer0, vmin,
                                 vmax, dv)
            # print('end of the 1st phase…', datetime.now() - time0)
            _fast_blur_2nd_phase(w, h, channels, radius, pixels, buffer0, vmin,
                                 vmax, dv)

        elif algotype == BlurType.PX_BOX_MULTI:
            full_buff = _fast_blur_1st_phase_multi(w, h, channels, radius, \
                                                         pixels, vmin, vmax, dv)
            # print('end of the 1st phase…', datetime.now() - time0)
            _fast_blur_2nd_phase(w, h, channels, radius, pixels, full_buff,
                                 vmin, vmax, dv)

        elif algotype == BlurType.CAIRO_BOX:
            original = _cairo_blur(radius, original)
        else:
            pass  # pas encore implémenté

        time1 = datetime.now()
        print('fast blur ended, total time:', time1 - time0)
    return original
示例#2
0
    def renderTo(self, fileName):
        xAttribs = self.xAttribs
        yAttribs = self.yAttribs
        xAttribs.setMinMax(self.xMin, self.xMax)

        # Create the image surface and cairo context
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
                                     330 + int(xAttribs.size + 0.5),
                                     55 + int(yAttribs.size + 0.5))
        cr = cairo.Context(surface)
        cr.set_source_rgb(1, 1, 1)
        cr.paint()
        cr.set_miter_limit(1.414)
        cr.translate(80, 8 + yAttribs.size)

        # Draw axes
        labelFont = createScaledFont('Arial', 13)
        with Saved(cr):
            cr.set_line_width(1)
            cr.set_source_rgb(.4, .4, .4)

            # Horizontal axis
            cr.move_to(0, -0.5)
            cr.rel_line_to(xAttribs.size + 1, 0)
            cr.stroke()
            for pos, label in xAttribs.iterLabels():  # Labels
                x = math.floor(pos + 0.5)
                with Saved(cr):
                    cr.translate(x, 9)
                    if int(label) == 1 or int(label) % 2 == 0:
                        fillAlignedText(cr, 0, 6, labelFont, label, 0.5)

            # Vertical axis
            cr.set_source_rgb(*colorTuple('f0f0f0'))
            for pos, label in yAttribs.iterLabels():  # Background lines
                if label == '0':
                    continue
                y = -math.floor(pos + 0.5) - 0.5
                cr.move_to(1, y)
                cr.rel_line_to(xAttribs.size + 1, 0)
            cr.stroke()
            cr.set_source_rgb(.4, .4, .4)
            cr.move_to(0.5, 0)
            cr.rel_line_to(0, -yAttribs.size - 0.5)
            if False:
                for pos, label in yAttribs.iterLabels():  # Tick marks
                    if label == '0':
                        continue
                    y = -math.floor(pos + 0.5) - 0.5
                    cr.move_to(1, y)
                    cr.rel_line_to(-4, 0)
            cr.stroke()
            for pos, label in yAttribs.iterLabels():  # Labels
                if label == '0':
                    continue
                #print pos
                #print label
                fillAlignedText(cr, -4, -pos + 4, labelFont, label, 1)
        """
        with Saved(cr):
            x = xAttribs.size - 70.5 + 80
            y = -234.5
            cr.rectangle(x, y, 120, 82)
            cr.set_source_rgb(*colorTuple('ffffff'))                
            cr.fill()
            cr.set_source_rgb(*colorTuple('f0f0f0'))                
            cr.rectangle(x, y, 120, 82)
            cr.set_line_width(1)
            cr.stroke()
        """

        # Draw curves
        for cn, curve in enumerate(self.curves):
            points = curve.points
            color = curve.color
            width = 1.75
            #if color == colorTuple('ff4040'):
            #width = 2
            with Saved(cr):
                cr.set_line_width(width)
                cr.set_source_rgba(*color)
                #if color == colorTuple('9090b0'):
                #    cr.set_dash([9, 2])
                with Saved(cr):
                    cr.rectangle(0, 5, xAttribs.size, -yAttribs.size - 15)
                    cr.clip()
                    x, y = points[0]
                    cr.move_to(xAttribs.mapAxisValue(x),
                               -yAttribs.mapAxisValue(y))
                    for x, y in points[1:]:
                        cr.line_to(
                            xAttribs.mapAxisValue(x) + 0.5,
                            -yAttribs.mapAxisValue(y) - 0.5)
                    cr.stroke()
                for x, y in points:
                    cr.rectangle(
                        xAttribs.mapAxisValue(x) - 2.5,
                        -yAttribs.mapAxisValue(y) - 2.5, 5, 5)
                cr.fill()

                x = xAttribs.size + 40
                y = -120 + (5 - cn) * 14
                cr.move_to(x - 4.5, y - 4.5)
                cr.rel_line_to(-21, 0)
                cr.stroke()

                # Label
                weight = cairo.FONT_WEIGHT_NORMAL
                if color == colorTuple('ff4040'):
                    weight = cairo.FONT_WEIGHT_BOLD
                labelFont = createScaledFont('Arial', 13, weight=weight)
                label = curve.name
                #x, y = points[-1]
                #fillAlignedText(cr, xAttribs.mapAxisValue(x) + 3, -yAttribs.mapAxisValue(y) + 4, labelFont, label, 0)
                x = xAttribs.size + 40
                y = -120 + (5 - cn) * 14
                fillAlignedText(cr, x, y, labelFont, label, 0)

        # Draw axis names
        cr.set_source_rgb(0, 0, 0)
        axisFont = createScaledFont('Helvetica',
                                    16,
                                    weight=cairo.FONT_WEIGHT_BOLD)
        with Saved(cr):
            cr.translate(-66, -yAttribs.size / 2.0)
            cr.rotate(-math.pi / 2)
            fillAlignedText(cr, 0, 0, axisFont, 'Map Operations / Sec', 0.5)
        with Saved(cr):
            axisFont2 = createScaledFont('Helvetica', 13)
            cr.translate(-50, -yAttribs.size / 2.0)
            cr.rotate(-math.pi / 2)
            cr.set_source_rgba(*colorTuple('808080'))
            fillAlignedText(cr, 0, 0, axisFont2, '(Total Across All Threads)',
                            0.5)
        fillAlignedText(cr, xAttribs.size / 2.0, 42, axisFont, 'Threads', 0.5)
        fillAlignedText(
            cr, xAttribs.size / 2.0, -450, axisFont,
            'Ops/sec vs. Number of threads with ' + str(readP) + '% reads, ' +
            str(insertP) + '% inserts, ' + str(removeP) + '% removes', 0.5)
        # Draw title

        # Save PNG file
        surface.write_to_png(fileName)
示例#3
0
def grafico(rotulos_valores, tipo = PIZZA, tamanho = (500, 500),
            rgb_fundo = (1, 1, 0.9), rgb_retangulo = (0.9, 0.9, 0.9),
            rgb_conteudo = (0, 0, 0.5), rgb_texto = (1, 1, 0),
            fundo_escala = None, percentual = True, ordem = None):
    "Retorna um gráfico em PNG dentro de um cStringIO"
    # Suporte gráfico com Cairo
    import cairo
    from math import pi, log
    largura, altura = tamanho
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, largura, altura)
    cr = cairo.Context(surface)
    # Fundo branco
    cr.set_source_rgb(*rgb_fundo)
    cr.paint()
    if ordem is not None:
        rotulos_valores = sorted(rotulos_valores, key=lambda x: x[1], reverse = ordem)
    if tipo == PIZZA:
        # Círculo, raio 5% menor
        raio = min(largura, altura) * 0.475
        cr.translate(largura / 2., altura / 2.)
        cr.set_source_rgb(*rgb_conteudo)
        cr.arc(0, 0, raio, 0, 2 * pi)
        cr.fill()
        cr.stroke()
        # Divisão do círculo
        cr.set_line_width(raio / 100.)
        cr.set_source_rgb(0, 0, 0)
        p = 0
        total = float(sum(zip(*rotulos_valores)[1]))
        for rotulo, valor in rotulos_valores:
            percentual = valor / total
            cr.move_to(0, 0)
            cr.arc(0, 0, raio, p * 2 * pi, (p + percentual) * 2 * pi)
            cr.save()
            if percentual:
                texto = "%s %.2f%%" % (rotulo, percentual * 100.)
            else:
                texto = "%s %.2f%%" % (rotulo, valor)
            size = raio / 10.
            height = size
            altura_maxima = 0
            while height - 2 > altura_maxima:
                cr.set_font_size(size)
                x_bearing, y_bearing, width, height, x_advance, y_advance = cr.text_extents(texto)
                distancia = 0.95 * raio - width
                altura_maxima = percentual * pi * distancia
                size -= 1
            angulo = (p + percentual / 2) * 2 * pi
            if pi / 2 < angulo < 3 * pi / 2:
                cr.rotate(angulo + pi)
                cr.move_to(-0.95 * raio - x_bearing, height/2.)
            else:
                cr.rotate(angulo)
                cr.move_to(0.95 * raio - width - x_bearing, height/2.)
            cr.set_source_rgb(*rgb_texto)
            cr.show_text(texto)
            cr.restore()
            p += percentual
        cr.stroke()
    else: # BARRAS ou LINHAS desenha o retângulo
        maior = max(zip(*rotulos_valores)[1])
        if not fundo_escala:
            exp = 10. ** int(log(maior, 10))
            fundo_escala = (int(maior / exp) + 1) * exp
        parte_escala = fundo_escala / 10.
        if maior > fundo_escala * 0.95:
            partes = int(maior / parte_escala) + 1
            escala = partes * parte_escala
            if maior > escala * 0.95:
                escala += parte_escala
                partes += 1
        else:
            escala = fundo_escala
            partes = 10
        cr.translate(0.025 * largura, 0.975 * altura)
        n = len(rotulos_valores)
        w = largura * 0.95
        wo = w / (n * 3 + 1)
        wi = wo * 2
        h = -altura * 0.95
        cr.set_line_width(-h / 200.)
        cr.rectangle(0, 0, w, h)
        cr.set_source_rgb(*rgb_retangulo)
        cr.fill()
        cr.stroke()
        cr.rectangle(0, 0, w, h)
        cr.set_source_rgb(0, 0, 0)
        cr.stroke()
        cr.set_line_width(-h / 1000.)
        for i in range(1, partes):
            cr.move_to(0, h * i / partes)
            cr.line_to(w, h * i / partes)
        cr.stroke()
        for i, (rotulo, valor) in enumerate(rotulos_valores):
            cr.rectangle(wo + (wi + wo) * i, 0, wi, valor/escala * h)
            cr.set_source_rgb(*rgb_conteudo)
            cr.fill()
            cr.stroke()
            cr.save()
            cr.set_font_size(wo)
            x_bearing, y_bearing, width, height, x_advance, y_advance = cr.text_extents(rotulo)
            if valor / escala * h - wo - x_advance - 20 > h:
                cr.move_to(wo + (wi + wo) * i + wi / 2 + height / 2, valor / escala * h - wo)
            else:
                cr.move_to(wo + (wi + wo) * i + wi / 2 + height / 2, valor / escala * h + wo + x_advance)
            cr.rotate(-pi / 2)
            cr.set_source_rgb(*rgb_texto)
            cr.show_text(rotulo)
            cr.restore()

    # Retornar PNG em cStringIO
    png_file = cStringIO.StringIO()
    surface.write_to_png(png_file)
    png_file.seek(0)
    return png_file
示例#4
0
            return None
        (width, height) = struct.unpack("=II", header)
        data = stream.read(width * height * 4)
        if len(data) < width * height * 4:
            log.warn("Corrupt _NET_WM_ICON")
            return None
    except Exception, e:
        log.warn("Weird corruption in _NET_WM_ICON: %s", e)
        return None
    # Cairo wants a native-endian array here, and since the icon is
    # transmitted as CARDINALs, that's what we get. It might seem more
    # sensible to use ImageSurface.create_for_data (at least it did to me!)
    # but then you end up with a surface that refers to the memory you pass in
    # directly, and also .get_data() doesn't work on it, and it breaks the
    # test suite and blah. This at least works, as odd as it is:
    surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
    # old versions of cairo do not have this method, just ignore it
    if not hasattr(surf, "get_data"):
        log.warn("Your Cairo is too old! Carrying on as best I can, "
                 "but don't expect a miracle")
        return None
    surf.get_data()[:] = data
    # Cairo uses premultiplied alpha. EWMH actually doesn't specify what it
    # uses, but apparently the de-facto standard is non-premultiplied. (At
    # least that's what Compiz's sources say.)
    if premultiply_argb_in_place:
        premultiply_argb_in_place(surf.get_data())
    return (width * height, surf)


# This returns a cairo ImageSurface which contains the largest icon defined in
示例#5
0
def white_borders(model, selection, pdfqueue):
    crop = []
    for path in selection:
        it = model.get_iter(path)
        p = model.get_value(it, 0)
        pdfdoc = pdfqueue[p.nfile - 1]

        page = pdfdoc.document.get_page(p.npage - 1)
        w, h = page.get_size()
        w = int(w)
        h = int(h)
        thumbnail = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
        cr = cairo.Context(thumbnail)
        page.render(cr)
        data = thumbnail.get_data().cast("i", shape=[h, w]).tolist()

        crop_this_page = [0.0, 0.0, 0.0, 0.0]

        # Left
        allwhite = True
        for col in range(w - 1):
            for row in range(h - 1):
                if data[row][col] != 0:
                    allwhite = False
                    crop_this_page[0] = (col) / w
                    break
            if not allwhite:
                break

        # Right
        allwhite = True
        for col in range(w - 1, 0, -1):
            for row in range(h - 1):
                if data[row][col] != 0:
                    allwhite = False
                    crop_this_page[1] = (w - col) / w
                    break
            if not allwhite:
                break

        # Top
        allwhite = True
        for row in range(h - 1):
            for col in range(w - 1):
                if data[row][col] != 0:
                    allwhite = False
                    crop_this_page[2] = (row) / h
                    break
            if not allwhite:
                break

        # Bottom
        allwhite = True
        for row in range(h - 1, 0, -1):
            for col in range(w - 1):
                if data[row][col] != 0:
                    allwhite = False
                    crop_this_page[3] = (h - row) / h
                    break
            if not allwhite:
                break

        crop.append(crop_this_page)
    return crop
示例#6
0
    def update_metadata(self, metadata):
        self._metadata.update(metadata)

        title = u(self._client.title)
        if title.find("@")>=0:
            #perform metadata variable substitutions:
            default_values = {"title" : u("<untitled window>"),
                              "client-machine" : u("<unknown machine>")}
            def metadata_replace(match):
                atvar = match.group(0)          #ie: '@title@'
                var = atvar[1:len(atvar)-1]     #ie: 'title'
                default_value = default_values.get(var, u("<unknown %s>") % var)
                value = self._metadata.get(var, default_value)
                return value.decode("utf-8")
            title = re.sub("@[\w\-]*@", metadata_replace, title)
        self.set_title(title)

        if "size-constraints" in self._metadata:
            size_metadata = self._metadata["size-constraints"]
            hints = {}
            for (a, h1, h2) in [
                ("maximum-size", "max_width", "max_height"),
                ("minimum-size", "min_width", "min_height"),
                ("base-size", "base_width", "base_height"),
                ("increment", "width_inc", "height_inc"),
                ]:
                if a in self._metadata["size-constraints"]:
                    hints[h1], hints[h2] = size_metadata[a]
            for (a, h) in [
                ("minimum-aspect", "min_aspect_ratio"),
                ("maximum-aspect", "max_aspect_ratio"),
                ]:
                if a in self._metadata:
                    hints[h] = size_metadata[a][0] * 1.0 / size_metadata[a][1]
            set_geometry_hints(self, hints)

        if hasattr(self, "get_realized"):
            #pygtk 2.22 and above have this method:
            realized = self.get_realized()
        else:
            #older versions:
            realized = self.flags() & gtk.REALIZED
        if not realized:
            self.set_wmclass(*self._metadata.get("class-instance",
                                                 ("xpra", "Xpra")))

        if "icon" in self._metadata:
            (width, height, coding, data) = self._metadata["icon"]
            if coding == "premult_argb32":
                cairo_surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
                cairo_surf.get_data()[:] = data
                # FIXME: We round-trip through PNG. This is ridiculous, but faster
                # than doing a bunch of alpha un-premultiplying and byte-swapping
                # by hand in Python (better still would be to write some Pyrex,
                # but I don't have time right now):
                loader = gdk.PixbufLoader()
                cairo_surf.write_to_png(loader)
                loader.close()
                pixbuf = loader.get_pixbuf()
            else:
                loader = gdk.PixbufLoader(coding)
                loader.write(data, len(data))
                loader.close()
                pixbuf = loader.get_pixbuf()
            self.set_icon(pixbuf)

        if "transient-for" in self._metadata:
            wid = self._metadata.get("transient-for")
            window = self._client._id_to_window.get(wid)
            log.debug("found transient-for: %s / %s", wid, window)
            if window:
                self.set_transient_for(window)

        if "window-type" in self._metadata:
            window_types = self._metadata.get("window-type")
            log.debug("window types=%s", window_types)
            for window_type in window_types:
                hint = NAME_TO_HINT.get(window_type)
                if hint:
                    log.debug("setting window type to %s - %s", window_type, hint)
                    self.set_type_hint(hint)
                    break
示例#7
0
    def renderTo(self, fileName):
        xAttribs = self.xAttribs
        yAttribs = self.yAttribs
        xAttribs.setMinMax(self.xMin, self.xMax)

        # Create the image surface and cairo context
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
                                     150 + int(xAttribs.size + 0.5),
                                     65 + int(yAttribs.size + 0.5))
        cr = cairo.Context(surface)
        cr.set_source_rgb(1, 1, 1)
        cr.paint()
        cr.set_miter_limit(1.414)
        cr.translate(58, 11 + yAttribs.size)

        # Draw axes
        labelFont = createScaledFont('Arial', 11)
        with Saved(cr):
            cr.set_line_width(1)
            cr.set_source_rgb(.4, .4, .4)

            # Horizontal axis
            cr.move_to(0, -0.5)
            cr.rel_line_to(xAttribs.size + 1, 0)
            for pos, label in xAttribs.iterLabels():  # Tick marks
                x = math.floor(pos + 0.5) + 0.5
                cr.move_to(x, -1)
                cr.rel_line_to(0, 4)
            cr.stroke()
            for pos, label in xAttribs.iterLabels():  # Labels
                x = math.floor(pos + 0.5)
                with Saved(cr):
                    cr.translate(x - 1, 5)
                    cr.rotate(-math.pi / 4)
                    fillAlignedText(cr, 0, 6, labelFont, label, 1)

            # Vertical axis
            cr.set_source_rgb(*colorTuple('f0f0f0'))
            for pos, label in yAttribs.iterLabels():  # Background lines
                if label == '0':
                    continue
                y = -math.floor(pos + 0.5) - 0.5
                cr.move_to(1, y)
                cr.rel_line_to(xAttribs.size + 1, 0)
            cr.stroke()
            cr.set_source_rgb(.4, .4, .4)
            cr.move_to(0.5, 0)
            cr.rel_line_to(0, -yAttribs.size - 0.5)
            if False:
                for pos, label in yAttribs.iterLabels():  # Tick marks
                    if label == '0':
                        continue
                    y = -math.floor(pos + 0.5) - 0.5
                    cr.move_to(1, y)
                    cr.rel_line_to(-4, 0)
            cr.stroke()
            for pos, label in yAttribs.iterLabels():  # Labels
                if label == '0':
                    continue
                fillAlignedText(cr, -4, -pos + 4, labelFont, label, 1)

        with Saved(cr):
            x = xAttribs.size - 70.5
            y = -234.5
            cr.rectangle(x, y, 120, 82)
            cr.set_source_rgb(*colorTuple('ffffff'))
            cr.fill()
            cr.set_source_rgb(*colorTuple('f0f0f0'))
            cr.rectangle(x, y, 120, 82)
            cr.set_line_width(1)
            cr.stroke()

        # Draw curves
        for cn, curve in enumerate(self.curves):
            points = curve.points
            width = 2.5
            color = curve.color
            with Saved(cr):
                cr.set_line_width(width)
                cr.set_source_rgba(*color)
                if cn in [1, 3, 5]:
                    cr.set_dash([10, 1])
                with Saved(cr):
                    cr.rectangle(0, 5, xAttribs.size, -yAttribs.size - 15)
                    cr.clip()
                    x, y = points[0]
                    cr.move_to(xAttribs.mapAxisValue(x),
                               -yAttribs.mapAxisValue(y))
                    for x, y in points[1:]:
                        cr.line_to(
                            xAttribs.mapAxisValue(x) + 0.5,
                            -yAttribs.mapAxisValue(y) - 0.5)
                    x = xAttribs.size - 40
                    y = -220 + cn * 12
                    cr.move_to(x - 4.5, y - 4.5)
                    cr.rel_line_to(-21, 0)
                    cr.stroke()

                # Label
                labelFont = createScaledFont('Arial', 11)
                label = curve.name
                #x, y = points[-1]
                #fillAlignedText(cr, xAttribs.mapAxisValue(x) + 3, -yAttribs.mapAxisValue(y) + 4, labelFont, label, 0)
                x = xAttribs.size - 40
                y = -220 + cn * 12
                fillAlignedText(cr, x, y, labelFont, label, 0)

        # Draw axis names
        cr.set_source_rgb(0, 0, 0)
        axisFont = createScaledFont('Helvetica',
                                    16,
                                    weight=cairo.FONT_WEIGHT_BOLD)
        with Saved(cr):
            cr.translate(-44, -yAttribs.size / 2.0)
            cr.rotate(-math.pi / 2)
            fillAlignedText(cr, 0, 0, axisFont, 'CPU Time Spent in Map', 0.5)
        fillAlignedText(cr, xAttribs.size / 2.0, 50, axisFont,
                        'Interval Between Map Operations', 0.5)

        # Save PNG file
        surface.write_to_png(fileName)
示例#8
0
 def setUp(self):
     self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
     self.context = cairo.Context(self.surface)
     self.tester = CairoSignalTester()
示例#9
0
    def draw(self, ctx=None, scale=1.0):
        """
        The main method to do the drawing.
        If ctx is given, we assume we draw draw raw on the cairo context ctx
        To draw in GTK3 and use the allocation, set ctx=None.
        Note: when drawing for display, to counter a Gtk issue with scrolling
        or resizing the drawing window, we draw on a surface, then copy to the
        drawing context when the Gtk 'draw' signal arrives.
        """
        # first do size request of what we will need
        halfdist = self.halfdist()
        if not ctx:  # Display
            if self.form == FORM_CIRCLE:
                size_w = size_h = 2 * halfdist
            elif self.form == FORM_HALFCIRCLE:
                size_w = 2 * halfdist
                size_h = halfdist + self.CENTER + PAD_PX
            elif self.form == FORM_QUADRANT:
                size_w = size_h = halfdist + self.CENTER + PAD_PX

            size_w_a = self.get_allocated_width()
            size_h_a = self.get_allocated_height()
            self.set_size_request(max(size_w, size_w_a), max(size_h, size_h_a))
            size_w = self.get_allocated_width()
            size_h = self.get_allocated_height()
            self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, size_w,
                                              size_h)
            ctx = cairo.Context(self.surface)
            self.center_xy = self.center_xy_from_delta()
            ctx.translate(*self.center_xy)
        else:  # printing
            if self.form == FORM_QUADRANT:
                self.center_xy = self.CENTER, halfdist
            else:
                self.center_xy = halfdist, halfdist
            ctx.scale(scale, scale)
            ctx.translate(*self.center_xy)

        ctx.save()
        # Draw center person:
        (person, dup, start, portion, dummy_parentfampos, dummy_nrfam,
         userdata, status) = self.gen2people[0][0]
        if person:
            #r, g, b, a = self.background_box(person, 0, userdata)
            (radiusin_pers, radiusout_pers, radiusin_partner,
             radiusout_partner) = self.get_radiusinout_for_gen_pair(0)
            if not self.innerring:
                radiusin_pers = TRANSLATE_PX
            self.draw_person(ctx,
                             person,
                             radiusin_pers,
                             radiusout_pers,
                             math.pi / 2,
                             math.pi / 2 + 2 * math.pi,
                             0,
                             False,
                             userdata,
                             is_central_person=True)
            #draw center to move chart
            ctx.set_source_rgb(0, 0, 0)  # black
            ctx.move_to(TRANSLATE_PX, 0)
            ctx.arc(0, 0, TRANSLATE_PX, 0, 2 * math.pi)
            if self.innerring:  # has at least one parent
                ctx.fill()
                self.draw_innerring_people(ctx)
            else:
                ctx.stroke()
        #now write all the families and children
        ctx.rotate(self.rotate_value * math.pi / 180)
        for gen in range(self.generations):
            (radiusin_pers, radiusout_pers, radiusin_partner,
             radiusout_partner) = self.get_radiusinout_for_gen_pair(gen)
            if gen > 0:
                for pdata in self.gen2people[gen]:
                    # person, duplicate or not, start angle, slice size,
                    #             parent pos in fam, nrfam, userdata, status
                    (pers, dup, start, portion, dummy_pospar, dummy_nrfam,
                     userdata, status) = pdata
                    if status != COLLAPSED:
                        self.draw_person(ctx,
                                         pers,
                                         radiusin_pers,
                                         radiusout_pers,
                                         start,
                                         start + portion,
                                         gen,
                                         dup,
                                         userdata,
                                         thick=status != NORMAL)
            #if gen < self.generations-1:
            for famdata in self.gen2fam[gen]:
                # family, duplicate or not, start angle, slice size,
                #       spouse pos in gen, nrchildren, userdata, status
                (fam, dup, start, portion, dummy_posfam, dummy_nrchild,
                 userdata, partner, status) = famdata
                if status != COLLAPSED:
                    more_pers_flag = (gen == self.generations - 1
                                      and fam.get_child_ref_list())
                    self.draw_person(ctx,
                                     partner,
                                     radiusin_partner,
                                     radiusout_partner,
                                     start,
                                     start + portion,
                                     gen,
                                     dup,
                                     userdata,
                                     thick=(status != NORMAL),
                                     has_moregen_indicator=more_pers_flag)
        ctx.restore()

        if self.background in [BACKGROUND_GRAD_AGE, BACKGROUND_GRAD_PERIOD]:
            self.draw_gradient_legend(ctx, halfdist)
示例#10
0
    def test_cairo_surface_full_in(self):
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
        Regress.test_cairo_surface_full_in(surface)

        with pytest.raises(TypeError):
            Regress.test_cairo_surface_full_in(object())
示例#11
0
 def test_region_from_py(self):
     surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10)
     context = cairo.Context(surface)
     region = cairo.Region(cairo.RectangleInt(0, 0, 42, 42))
     Gdk.cairo_region(context, region)
     self.assertTrue("42" in repr(list(context.copy_path())))
    def parse_data(self):
        if self.skin is not None and\
                os.path.exists(os.path.join(self.skin, 'skin')):
            maindir = self.skin
            ans = self.read_main_data()
            if ans is not None and self.weather_data is not None:
                mainsurface = cairo.ImageSurface(cairo.FORMAT_ARGB32, ans[0],
                                                 ans[1])
                cr = cairo.Context(mainsurface)
                # try:
                for index, line in enumerate(self.widgetdata.split('\n')):
                    row = line.split('|')
                    cr.save()
                    if row is not None and len(row) > 1:
                        if row[0] == 'CLOCK':
                            print(row)
                            atype, minutesorhours, fileimage, x, y, width,\
                                height, xpos, ypos = row
                            fileimage = os.path.join(maindir, fileimage)
                            x = float(x)
                            y = float(y)
                            width = float(width)
                            height = float(height)
                            surface = get_surface_from_file(fileimage)
                            print(surface.get_width(), surface.get_height())
                            if surface is not None:
                                s_width = surface.get_width()
                                s_height = surface.get_height()
                                if xpos == 'CENTER':
                                    x = x - width / 2.0
                                elif xpos == 'RIGHT':
                                    x = x - width
                                if ypos == 'CENTER':
                                    y = y - height / 2.0
                                elif ypos == 'BOTTOM':
                                    y = y - height
                                hours = float(
                                    self.weather_data['current_conditions']
                                    ['rawOffset'])
                                now = self.datetime +\
                                    datetime.timedelta(hours=hours)
                                atime = float(
                                    now.hour) + float(now.minute) / 60.0
                                hours = atime
                                if not self.a24h and hours > 12:
                                    hours -= 12.0
                                minutes = (atime - int(atime)) * 60.0
                                cr.translate(x, y)
                                cr.scale(width / s_width, height / s_height)
                                if minutesorhours == '$HOUR$':
                                    cr.rotate(2.0 * math.pi / 12.0 * hours -
                                              math.pi / 2.0)
                                elif minutesorhours == '$MINUTES$':
                                    cr.rotate(2.0 * math.pi / 60.0 * minutes -
                                              math.pi / 2.0)
                                cr.set_source_surface(surface)
                                cr.paint()
                        elif row[0] == 'IMAGE':
                            atype, fileimage, x, y, width, height, xpos, ypos = row
                            if self.weather_data is not None:
                                if fileimage == '$CONDITION$':
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['current_conditions']
                                        ['condition_image'])
                                elif fileimage == '$CONDITION_ICON_LIGHT$':
                                    fileimage = os.path.join(
                                        comun.ICONDIR,
                                        self.weather_data['current_conditions']
                                        ['condition_icon_light'])
                                elif fileimage == '$CONDITION_ICON_DARK':
                                    fileimage = os.path.join(
                                        comun.ICONDIR,
                                        self.weather_data['current_conditions']
                                        ['condition_icon_dark'])
                                elif fileimage == '$MOONPHASE$':
                                    fileimage = os.path.join(
                                        comun.IMAGESDIR,
                                        self.weather_data['current_conditions']
                                        ['moon_icon'])
                                elif fileimage == '$WIND$':
                                    fileimage = os.path.join(
                                        comun.IMAGESDIR,
                                        self.weather_data['current_conditions']
                                        ['wind_icon'])
                                elif fileimage == '$CONDITION_01$' and len(
                                        self.weather_data['forecasts']) > 0:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][0]
                                        ['condition_image'])
                                elif fileimage == '$CONDITION_02$' and len(
                                        self.weather_data['forecasts']) > 1:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][1]
                                        ['condition_image'])
                                elif fileimage == '$CONDITION_03$' and len(
                                        self.weather_data['forecasts']) > 2:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][2]
                                        ['condition_image'])
                                elif fileimage == '$CONDITION_04$' and len(
                                        self.weather_data['forecasts']) > 3:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][3]
                                        ['condition_image'])
                                elif fileimage == '$CONDITION_05$' and len(
                                        self.weather_data['forecasts']) > 4:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][4]
                                        ['condition_image'])
                                elif fileimage == '$MOONPHASE_01$' and len(
                                        self.weather_data['forecasts']) > 0:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][0]
                                        ['moon_phase'])
                                elif fileimage == '$MOONPHASE_02$' and len(
                                        self.weather_data['forecasts']) > 1:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][1]
                                        ['moon_phase'])
                                elif fileimage == '$MOONPHASE_03$' and len(
                                        self.weather_data['forecasts']) > 2:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][2]
                                        ['moon_phase'])
                                elif fileimage == '$MOONPHASE_04$' and len(
                                        self.weather_data['forecasts']) > 3:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][3]
                                        ['moon_phase'])
                                elif fileimage == '$MOONPHASE_05$' and len(
                                        self.weather_data['forecasts']) > 4:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][4]
                                        ['moon_phase'])
                                elif fileimage == '$WIND_01$' and len(
                                        self.weather_data['forecasts']) > 0:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][0]
                                        ['wind_icon'])
                                elif fileimage == '$WIND_02$' and len(
                                        self.weather_data['forecasts']) > 1:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][1]
                                        ['wind_icon'])
                                elif fileimage == '$WIND_03$' and len(
                                        self.weather_data['forecasts']) > 2:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][2]
                                        ['wind_icon'])
                                elif fileimage == '$WIND_04$' and len(
                                        self.weather_data['forecasts']) > 3:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][3]
                                        ['wind_icon'])
                                elif fileimage == '$WIND_05$' and len(
                                        self.weather_data['forecasts']) > 4:
                                    fileimage = os.path.join(
                                        comun.WIMAGESDIR,
                                        self.weather_data['forecasts'][4]
                                        ['wind_icon'])
                                else:
                                    fileimage = os.path.join(
                                        maindir, fileimage)
                            else:
                                fileimage = os.path.join(maindir, fileimage)
                            x = float(x)
                            y = float(y)
                            width = float(width)
                            height = float(height)
                            surface = get_surface_from_file(fileimage)
                            if surface is not None:
                                s_width = surface.get_width()
                                s_height = surface.get_height()
                                if xpos == 'CENTER':
                                    x = x - width / 2.0
                                elif xpos == 'RIGHT':
                                    x = x - width
                                if ypos == 'CENTER':
                                    y = y - height / 2.0
                                elif ypos == 'BOTTOM':
                                    y = y - height
                                cr.translate(x, y)
                                cr.scale(width / s_width, height / s_height)
                                cr.set_source_surface(surface)
                                cr.paint()
                        elif row[0] == 'TEXT':
                            atype, text, x, y, font, size, color, xpos, ypos = row
                            x = float(x)
                            y = float(y)
                            size = int(size)
                            r, g, b, a = color.split(',')
                            cr.set_source_rgba(float(r), float(g), float(b),
                                               float(a))
                            cr.select_font_face(font)
                            cr.set_font_size(size)
                            now = self.datetime + datetime.timedelta(
                                hours=float(
                                    self.weather_data['current_conditions']
                                    ['rawOffset']))
                            if self.parse_time:
                                now = self.datetime + datetime.timedelta(
                                    hours=float(
                                        self.weather_data['current_conditions']
                                        ['rawOffset']))
                                hours = now.hour
                                if not self.a24h:
                                    if hours > 12:
                                        hours -= 12
                                    if hours < 1:
                                        hours += 12
                                hours = str(hours)
                                hours = '0' * (2 - len(hours)) + hours
                                minutes = str(now.minute)
                                minutes = '0' * (2 - len(minutes)) + minutes
                                if text.find('$HOUR$') > -1:
                                    text = text.replace('$HOUR$', hours)
                                if text.find('$MINUTES$') > -1:
                                    text = text.replace('$MINUTES$', minutes)
                            if text.find('$WEEKDAY$') > -1:
                                text = text.replace('$WEEKDAY$',
                                                    now.strftime('%A'))
                            if text.find('$DAY$') > -1:
                                text = text.replace('$DAY$',
                                                    now.strftime('%d'))
                            if text.find('$MONTH$') > -1:
                                text = text.replace('$MONTH$',
                                                    now.strftime('%m'))
                            if text.find('$MONTHNAME$') > -1:
                                text = text.replace('$MONTHNAME$',
                                                    now.strftime('%B'))
                            if text.find('$YEAR$') > -1:
                                text = text.replace('$YEAR$',
                                                    now.strftime('%Y'))
                            if text.find('$LOCATION$'
                                         ) > -1 and self.location is not None:
                                text = text.replace('$LOCATION$',
                                                    self.location)
                            if self.weather_data is not None:
                                if text.find('$TEMPERATURE$') > -1:
                                    text = text.replace(
                                        '$TEMPERATURE$', '{0}{1:c}'.format(
                                            self.
                                            weather_data['current_conditions']
                                            ['temperature'], 176))
                                if text.find('$MAX_TEMPERATURE$') > -1:
                                    text = text.replace(
                                        '$MAX_TEMPERATURE$', '{0}{1:c}'.format(
                                            self.weather_data['forecasts'][0]
                                            ['high'], 176))
                                if text.find('$MIN_TEMPERATURE$') > -1:
                                    text = text.replace(
                                        '$MIN_TEMPERATURE$', '{0}{1:c}'.format(
                                            self.weather_data['forecasts'][0]
                                            ['low'], 176))
                                if text.find('$HUMIDITY$') > -1:
                                    text = text.replace(
                                        '$HUMIDITY$',
                                        self.weather_data['current_conditions']
                                        ['humidity'])
                                if text.find('$PRESSURE$') > -1:
                                    text = text.replace(
                                        '$PRESSURE$',
                                        self.weather_data['current_conditions']
                                        ['pressure'])
                                if text.find('$WIND$') > -1:
                                    text = text.replace(
                                        '$WIND$',
                                        self.weather_data['current_conditions']
                                        ['wind_condition'])
                                if text.find('$CONDITION$') > -1:
                                    text = text.replace(
                                        '$CONDITION$',
                                        self.weather_data['current_conditions']
                                        ['condition_text'])
                                if len(self.weather_data['forecasts']) > 0:
                                    if text.find('$MAX_TEMPERATURE_01$') > -1:
                                        text = text.replace(
                                            '$MAX_TEMPERATURE_01$',
                                            self.weather_data['forecasts'][0]
                                            ['high'])
                                    if text.find('$MIN_TEMPERATURE_01$') > -1:
                                        text = text.replace(
                                            '$MIN_TEMPERATURE_01$',
                                            self.weather_data['forecasts'][0]
                                            ['low'])
                                    if text.find('$CONDITION_01$') > -1:
                                        text = text.replace(
                                            '$CONDITION_01$',
                                            self.weather_data['forecasts'][0]
                                            ['condition_text'])
                                    if text.find('$DAY_OF_WEEK_01$') > -1:
                                        text = text.replace(
                                            '$DAY_OF_WEEK_01$',
                                            self.weather_data['forecasts'][0]
                                            ['day_of_week'])
                                if len(self.weather_data['forecasts']) > 1:
                                    if text.find('$MAX_TEMPERATURE_02$') > -1:
                                        text = text.replace(
                                            '$MAX_TEMPERATURE_02$',
                                            self.weather_data['forecasts'][1]
                                            ['high'])
                                    if text.find('$MIN_TEMPERATURE_02$') > -1:
                                        text = text.replace(
                                            '$MIN_TEMPERATURE_02$',
                                            self.weather_data['forecasts'][1]
                                            ['low'])
                                    if text.find('$CONDITION_02$') > -1:
                                        text = text.replace(
                                            '$CONDITION_02$',
                                            self.weather_data['forecasts'][1]
                                            ['condition_text'])
                                    if text.find('$DAY_OF_WEEK_02$') > -1:
                                        text = text.replace(
                                            '$DAY_OF_WEEK_02$',
                                            self.weather_data['forecasts'][1]
                                            ['day_of_week'])
                                if len(self.weather_data['forecasts']) > 2:
                                    if text.find('$MAX_TEMPERATURE_03$') > -1:
                                        text = text.replace(
                                            '$MAX_TEMPERATURE_03$',
                                            self.weather_data['forecasts'][2]
                                            ['high'])
                                    if text.find('$MIN_TEMPERATURE_03$') > -1:
                                        text = text.replace(
                                            '$MIN_TEMPERATURE_03$',
                                            self.weather_data['forecasts'][2]
                                            ['low'])
                                    if text.find('$CONDITION_03$') > -1:
                                        text = text.replace(
                                            '$CONDITION_03$',
                                            self.weather_data['forecasts'][2]
                                            ['condition_text'])
                                    if text.find('$DAY_OF_WEEK_03$') > -1:
                                        text = text.replace(
                                            '$DAY_OF_WEEK_03$',
                                            self.weather_data['forecasts'][2]
                                            ['day_of_week'])
                                if len(self.weather_data['forecasts']) > 3:
                                    if text.find('$MAX_TEMPERATURE_04$') > -1:
                                        text = text.replace(
                                            '$MAX_TEMPERATURE_04$',
                                            self.weather_data['forecasts'][3]
                                            ['high'])
                                    if text.find('$MIN_TEMPERATURE_04$') > -1:
                                        text = text.replace(
                                            '$MIN_TEMPERATURE_04$',
                                            self.weather_data['forecasts'][3]
                                            ['low'])
                                    if text.find('$CONDITION_04$') > -1:
                                        text = text.replace(
                                            '$CONDITION_04$',
                                            self.weather_data['forecasts'][3]
                                            ['condition_text'])
                                    if text.find('$DAY_OF_WEEK_04$') > -1:
                                        text = text.replace(
                                            '$DAY_OF_WEEK_04$',
                                            self.weather_data['forecasts'][3]
                                            ['day_of_week'])
                                if len(self.weather_data['forecasts']) > 4:
                                    if text.find('$MAX_TEMPERATURE_05$') > -1:
                                        text = text.replace(
                                            '$MAX_TEMPERATURE_05$',
                                            self.weather_data['forecasts'][4]
                                            ['high'])
                                    if text.find('$MIN_TEMPERATURE_05$') > -1:
                                        text = text.replace(
                                            '$MIN_TEMPERATURE_05$',
                                            self.weather_data['forecasts'][4]
                                            ['low'])
                                    if text.find('$CONDITION_05$') > -1:
                                        text = text.replace(
                                            '$CONDITION_05$',
                                            self.weather_data['forecasts'][4]
                                            ['condition_text'])
                                    if text.find('$DAY_OF_WEEK_05$') > -1:
                                        text = text.replace(
                                            '$DAY_OF_WEEK_05$',
                                            self.weather_data['forecasts'][4]
                                            ['day_of_week'])

                            x_bearing, y_bearing, width, height, x_advance, y_advance = cr.text_extents(
                                text)
                            if xpos == 'CENTER':
                                x = x - width / 2.0
                            elif xpos == 'RIGHT':
                                x = x - width
                            if ypos == 'CENTER':
                                y = y + height / 2.0
                            elif ypos == 'TOP':
                                y = y + height
                            cr.move_to(x, y)
                            cr.show_text(text)
                    cr.restore()
                self.surface = mainsurface
                return
                # except Exception as e:
                #   print('Parsing data error: %s'%e)
        self.surface = None
示例#13
0
def FillPath(ctx,page,i):
    ctx.save()
    matrix = cairo.Matrix(1./page.width,0,0,1./page.height,0,0)
    ctx.transform(matrix)
    eonum = page.curbg
    if eonum == 0x80000005 or page.mfobjs[eonum].style == 1: ## bkmode is temporary before hatch/bitmap brushes
        print 'NO FILL'
        pass
    else:
        eo = page.mfobjs[eonum]
        if eo.style == 2 or eo.style == 3:
            if eo.style == 2:
                data = darr[eo.hatch]
                w,h = 8,8
            if eo.style == 3:
                w = eo.data[0]
                h = eo.data[1]
                bmpsize = struct.pack('<I',eo.data[2])
                bmpshift = struct.pack('<I',eo.data[3])
                bmp = '\x42\x4d'+bmpsize+'\x00\x00\x00\x00'+bmpshift+eo.data[4]
                pixbufloader = gtk.gdk.PixbufLoader()
                pixbufloader.write(bmp)
                pixbufloader.close()
                pixbuf = pixbufloader.get_pixbuf()
                cs = cairo.ImageSurface(0,w,h)
                ct = cairo.Context(cs)
                ct2 = gtk.gdk.CairoContext(ct)
                ct2.set_source_pixbuf(pixbuf,0,0)
                ct2.paint()
            if page.bkmode == 2:
                r = page.bkcolor.r
                g = page.bkcolor.g
                b = page.bkcolor.b
                ctx.set_source_rgba(r/255.,g/255.,b/255.,page.alpha)
                ctx.fill_preserve()
            StrokePathPreserve(ctx,page,i)
            if eo.flag !=1:
                r,g,b = eo.clr.r,eo.clr.g,eo.clr.b
            else:
                clr = page.palette[eo.clr.r]  ## FIXME! have to be 2 byte made of R and G.
                r,g,b = clr.r,clr.g,clr.b
                
            ctx.set_source_rgba(r/255.,g/255.,b/255.,page.alpha)

            if eo.style != 3:
                cs = cairo.ImageSurface.create_for_data(data,3,w,h,1)
                pat = cairo.SurfacePattern(cs)
                pat.set_filter(5)
                pat.set_extend(1)
                ctx.save()
                ctx.clip()
                ctx.scale(.8/page.scale+0.5,.8/page.scale+0.5)
                ctx.mask(pat)
                ctx.restore()
            else:
                pat = cairo.SurfacePattern(cs)
                pat.set_filter(5)
                pat.set_extend(1)
                ctx.save()
                ctx.clip()
                ctx.scale(.8/page.scale+0.5,.8/page.scale+0.5)
                ctx.set_source(pat)
                ctx.paint()
                ctx.restore()
        else:
            if eo.flag !=1:
                r,g,b = eo.clr.r,eo.clr.g,eo.clr.b
            else:
                clr = page.palette[eo.clr.r]  ## FIXME! have to be 2 byte made of R and G.
                r,g,b = ord(clr.r),ord(clr.g),ord(clr.b)

            ctx.set_source_rgba(r/255.,g/255.,b/255.,page.alpha)
            ctx.fill_preserve()
            print 'FILL:',r,g,b
    ctx.restore()
 def __init__(self, widget_cls, *args, **kwargs):
     self.window = GuiDriverWindow()
     self.cairo_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 800, 600)
     self.canvas = smartnotes.CairoCanvas(self.cairo_surface)
     self.widget = widget_cls(self.window, None, *args, **kwargs)
示例#15
0
def test_scaled_font_get_font_options():
    surface = cairo.ImageSurface(0, 10, 10)
    ctx = cairo.Context(surface)
    sf = ctx.get_scaled_font()
    font_options = sf.get_font_options()
    assert isinstance(font_options, cairo.FontOptions)
示例#16
0
parser.add_option("--height", type="int", default=600, help="Height")
parser.add_option("--bights", type="int", default=4, help="Bights")
parser.add_option("--leads", type="int", default=3, help="Leads")
parser.add_option("--radius-variation",
                  type="int",
                  default=200,
                  help="Radius variation")
parser.add_option("--line-width", type="int", default=50, help="Line width")
parser.add_option("--output",
                  type="string",
                  default="turkshead.png",
                  help="Output file")
options, arguments = parser.parse_args()

width = options.width
height = options.height
outerRadius = min(width, height) / 2 - 10
innerRadius = outerRadius - options.radius_variation

img = cairo.ImageSurface(cairo.FORMAT_RGB24, width, height)
ctx = cairo.Context(img)
ctx.set_source_rgb(1, 1, 0xBF / 255.)
ctx.paint()
ctx.translate(width / 2, height / 2)
ctx.scale(1, -1)

TurksHead(options.bights, options.leads, innerRadius, outerRadius,
          options.line_width).draw(ctx)

img.write_to_png(options.output)
示例#17
0
文件: canvas.py 项目: zcy330/sk1-wx
 def __init__(self, canvas):
     self.canvas = canvas
     self.surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1)
     self.ctx = cairo.Context(self.surface)
示例#18
0
def vote_thumbnail_image(request, congress, session, chamber_code, number,
                         image_type):
    vote = load_vote(congress, session, chamber_code, number)

    import cairo, re, math
    from StringIO import StringIO

    # general image properties
    font_face = "DejaVu Serif Condensed"
    image_width = 300
    image_height = 250 if image_type == "thumbnail" else 170

    # format text to print on the image
    vote_title = re.sub(r"^On the Motion to ", "To ", vote.question)
    if re.match(r"Cloture .*Rejected", vote.result):
        vote_result_2 = "Filibustered"
    elif re.match(r"Cloture .*Agreed to", vote.result):
        vote_result_2 = "Proceed"
    else:
        vote_result_2 = re.sub(
            "^(Bill|Amendment|Resolution|Conference Report|Nomination|Motion to \S+) ",
            "", vote.result)
    if vote_result_2 == "unknown": vote_result_2 = ""
    vote_date = vote.created.strftime(
        "%x") if vote.created.year > 1900 else vote.created.isoformat().split(
            "T")[0]
    vote_citation = vote.get_chamber_display() + " Vote #" + str(
        vote.number) + " -- " + vote_date

    # get vote totals by option and by party
    totals = vote.totals()
    total_count = 0
    total_counts = {}  # key: total ({ "+": 123 }, etc.)
    yea_counts_by_party = [0, 0, 0]  # D, I, R (+ votes totals)
    nay_counts_by_party = [0, 0, 0]  # D, I, R (+/- votes totals)
    nonvoting_members_totals = [0, 0, 0]  # D, I, R
    party_index = {"Democrat": 0, "Republican": 2}
    for opt in totals["options"]:
        total_counts[opt["option"].key] = opt["count"]
        for i in xrange(len(totals["parties"])):
            j = party_index.get(totals["parties"][i], 1)
            if opt["option"].key not in ("+", "-"):
                # most votes are by proportion of those voting (not some cloture etc.),
                # so put present/not-voting tallies in a separate group
                nonvoting_members_totals[j] += opt["party_counts"][i]["count"]
                continue
            total_count += opt["party_counts"][i]["count"]
            if opt["option"].key == "+":
                yea_counts_by_party[j] += opt["party_counts"][i]["count"]
            else:
                nay_counts_by_party[j] += opt["party_counts"][i]["count"]
    if total_count == 0 or "+" not in total_counts or "-" not in total_counts:
        raise Http404()  # no thumbnail for other sorts of votes
    vote_result_1 = "%d-%d" % (total_counts["+"], total_counts["-"])

    def show_text_centered(ctx, text, max_width=None):
        while True:
            (x_bearing, y_bearing, width, height, x_advance,
             y_advance) = ctx.text_extents(text)
            if max_width is not None and width > max_width:
                text2 = re.sub(r" \S+(\.\.\.)?$", "...", text)
                if text2 != text:
                    text = text2
                    continue
            break

        ctx.rel_move_to(-width / 2, height)
        ctx.show_text(text)

    im = cairo.ImageSurface(cairo.FORMAT_ARGB32, image_width, image_height)
    ctx = cairo.Context(im)

    ctx.select_font_face(font_face, cairo.FONT_SLANT_NORMAL,
                         cairo.FONT_WEIGHT_BOLD)

    # clear background
    ctx.set_source_rgb(1, 1, 1)
    ctx.new_path()
    ctx.line_to(0, 0)
    ctx.line_to(image_width, 0)
    ctx.line_to(image_width, image_height)
    ctx.line_to(0, image_height)
    ctx.fill()

    chart_top = 0
    if image_type == "thumbnail":
        # Title
        ctx.set_font_size(20)
        ctx.set_source_rgb(.2, .2, .2)
        ctx.move_to(150, 10)
        show_text_centered(ctx, vote_title, max_width=.95 * image_width)
        chart_top = 50

    # Vote Tally
    font_size = 26 if len(vote_result_2) < 10 else 22
    ctx.set_font_size(font_size)
    ctx.set_source_rgb(.1, .1, .1)
    ctx.move_to(150, chart_top)
    show_text_centered(ctx, vote_result_1)

    # Vote Result
    ctx.move_to(150, chart_top + 12 + font_size)
    show_text_centered(ctx, vote_result_2)
    w = max(
        ctx.text_extents(vote_result_1)[2],
        ctx.text_extents(vote_result_2)[2])

    # Line
    ctx.set_line_width(1)
    ctx.new_path()
    ctx.line_to(150 - w / 2, chart_top + 5 + font_size)
    ctx.rel_line_to(w, 0)
    ctx.stroke()

    if image_type == "thumbnail":
        # Vote Chamber/Date/Number
        ctx.select_font_face(font_face, cairo.FONT_SLANT_NORMAL,
                             cairo.FONT_WEIGHT_NORMAL)
        ctx.set_font_size(14)
        ctx.move_to(150, image_height - 25)
        show_text_centered(ctx, vote_citation, max_width=.98 * image_width)

    # Seats

    # Construct an array of rows of seats, where each entry maps to a particular
    # voter.

    # How many rows of seats? That is hard coded by chamber.
    seating_rows = 8 if vote.chamber == CongressChamber.house else 4
    # 4 for Senate (http://www.senate.gov/artandhistory/art/special/Desks/chambermap.cfm)
    # about 8 for the House

    # Long ago Congress had very few people.
    seating_rows = min(total_count / 8 + 1, seating_rows)

    # Determine the seating chart dimensions: the radius of the inside row of
    # seats and the radius of the outside row of seats.
    inner_r = w / 2 * 1.25 + 5  # wrap closely around the text in the middle
    if seating_rows <= 4:
        inner_r = max(inner_r, 75)  # don't make the inner radius too small
    outer_r = image_width * .45  # end close to the image width

    # If we assume the absolute spacing of seats is constant from row to row, then
    # the number of seats per row grows linearly with the radius, following the
    # circumference. If s0 is the number of seats on the inner row, then
    # floor(s0 * outer_r/inner_r) is the number of seats on the outer row. The total
    # number of seats is found by the sum of the arithmetic sequence (n/2 * (a_1+a_n)):
    #  n = (seating_rows/2)*(s0 + s0*outer_r/inner_r)
    # We want exactly total_count seats, so solving for s0...
    seats_per_row = 2.0 * total_count / (seating_rows *
                                         (1.0 + outer_r / inner_r))

    # How wide to draw a seat?
    seat_size = min(.8 * (outer_r - inner_r) / seating_rows,
                    .35 * (2 * 3.14159 * inner_r) / seats_per_row)

    # Determine how many seats on each row.
    seats_so_far = 0
    rowcounts = []
    for row in xrange(seating_rows):
        # What's the radius of this row?
        if seating_rows > 1:
            r = inner_r + (outer_r - inner_r) * row / float(seating_rows - 1)
        else:
            r = inner_r

        # How many seats should we put on this row?
        if row < seating_rows - 1:
            # Start with seats_per_row on the inner row and grow linearly.
            # Round to an integer. Alternate rounding down and up.
            n_seats = seats_per_row * r / inner_r
            n_seats = int(
                math.floor(n_seats) if (row % 2 == 0) else math.ceil(n_seats))
        else:
            # On the outermost row, just put in how many left we need
            # so we always have exactly the right number of seats.
            n_seats = total_count - seats_so_far

        rowcounts.append(n_seats)
        seats_so_far += n_seats

    # Make a list of all of the seats as a list of tuples of the
    # form (rownum, seatnum) where seatnum is an index from the
    # left side.
    seats = []
    for row, count in enumerate(rowcounts):
        for i in xrange(count):
            seats.append((row, i))

    # Sort the seats in the order we will fill them from left to right,
    # bottom to top.
    seats.sort(
        key=lambda seat: (seat[1] / float(rowcounts[seat[0]]), -seat[0]))

    # We can draw in two modes. In one mode, we don't care which actual
    # person corresponds to which seat. We just draw the groups of voters
    # in blocks. Or we can draw the actual people in seats we assign
    # according to their ideology score, from left to right.

    # See if we have ideology scores.
    voter_details = None
    if True:
        global ideology_scores
        load_ideology_scores(vote.congress)
        if ideology_scores[vote.congress]:
            voter_details = []

            # Load the voters, getting their role at the time they voted.
            voters = list(vote.voters.all().select_related('person', 'option'))
            load_roles_at_date([x.person for x in voters if x.person != None],
                               vote.created)

            # Store ideology scores
            for voter in voters:
                if voter.option.key not in ("+", "-"): continue
                party = party_index.get(
                    voter.person.role.party
                    if voter.person and voter.person.role else "Unknown", 1)
                option = 0 if voter.option.key == "+" else 1
                coord = ideology_scores[vote.congress].get(
                    voter.person.id if voter.person else "UNKNOWN",
                    ideology_scores[vote.congress].get(
                        "MEDIAN:" + (voter.person.role.party if voter.person
                                     and voter.person.role else ""),
                        ideology_scores[vote.congress]["MEDIAN"]))
                voter_details.append((coord, (party, option)))

            # Sort voters by party, then by ideology score, then by vote.
            voter_details.sort(key=lambda x: (x[1][0], x[0], x[1][1]))

            if len(voter_details) != len(seats):
                raise ValueError("Gotta check this.")
                voter_details = None  # abort

    if not voter_details:
        # Just assign voters to seats in blocks.
        #
        # We're fill the seats from left to right different groups of voters:
        #   D+, D-, I+, I-, R-, R+
        # For each group, for each voter in the group, pop off a seat and
        # draw him in that seat.

        # for each group of voters...
        seat_idx = 0
        for (party, vote) in [(0, 0), (0, 1), (1, 0), (1, 1), (2, 1), (2, 0)]:
            # how many votes in this group?
            n_voters = (yea_counts_by_party
                        if vote == 0 else nay_counts_by_party)[party]
            # for each voter...
            for i in xrange(n_voters):
                seats[seat_idx] = (seats[seat_idx], (party, vote))
                seat_idx += 1

    else:
        # Assign voters to seats in order.
        for i in xrange(len(voter_details)):
            seats[i] = (seats[i], voter_details[i][1])

    # Draw the seats.

    group_colors = {
        (0, 0): (0.05, 0.24, 0.63),  # D+
        (0, 1): (0.85, 0.85, 1.0),  # D-
        (1, 0): (0.07, 0.05, 0.07),  # I+
        (1, 1): (0.85, 0.85, 0.85),  # I-
        (2, 0): (0.90, 0.05, 0.07),  # R+
        (2, 1): (1.0, 0.85, 0.85),  # R-
    }

    for ((row, seat_pos), (party, vote)) in seats:
        # radius of this row (again, code dup)
        if seating_rows > 1:
            r = inner_r + (outer_r - inner_r) * row / float(seating_rows - 1)
        else:
            r = inner_r

        # draw
        ctx.set_source_rgb(*group_colors[(party, vote)])
        ctx.identity_matrix()
        ctx.translate(image_width / 2, chart_top + 25)
        ctx.rotate(3.14159 - 3.14159 * seat_pos / float(rowcounts[row] - 1))
        ctx.translate(r, 0)
        ctx.rectangle(-seat_size / 2, -seat_size / 2, seat_size, seat_size)
        ctx.fill()

    # Convert the image buffer to raw PNG bytes.
    buf = StringIO()
    im.write_to_png(buf)
    v = buf.getvalue()

    # Form the response.
    r = HttpResponse(v, content_type='image/png')
    r["Content-Length"] = len(v)
    return r
示例#19
0
    def __init__(self, target=None, bbox=None, palette=None, background=None):
        """Creates a new plot.

        @param target: the target surface to write to. It can be one of the
          following types:

            - C{None} -- an appropriate surface will be created and the object
              will be plotted there.

            - C{cairo.Surface} -- the given Cairo surface will be used.

            - C{string} -- a file with the given name will be created and an
              appropriate Cairo surface will be attached to it.

        @param bbox: the bounding box of the surface. It is interpreted
          differently with different surfaces: PDF and PS surfaces will
          treat it as points (1 point = 1/72 inch). Image surfaces will
          treat it as pixels. SVG surfaces will treat it as an abstract
          unit, but it will mostly be interpreted as pixels when viewing
          the SVG file in Firefox.

        @param palette: the palette primarily used on the plot if the
          added objects do not specify a private palette. Must be either
          an L{igraph.drawing.colors.Palette} object or a string referring
          to a valid key of C{igraph.drawing.colors.palettes} (see module
          L{igraph.drawing.colors}) or C{None}. In the latter case, the default
          palette given by the configuration key C{plotting.palette} is used.

        @param background: the background color. If C{None}, the background
          will be transparent. You can use any color specification here that
          is understood by L{igraph.drawing.colors.color_name_to_rgba}.
        """
        self._filename = None
        self._surface_was_created = not isinstance(target, cairo.Surface)
        self._need_tmpfile = False

        # Several Windows-specific hacks will be used from now on, thanks
        # to Dale Hunscher for debugging and fixing all that stuff
        self._windows_hacks = "Windows" in platform.platform()

        if bbox is None:
            self.bbox = BoundingBox(600, 600)
        elif isinstance(bbox, tuple) or isinstance(bbox, list):
            self.bbox = BoundingBox(bbox)
        else:
            self.bbox = bbox

        if palette is None:
            config = Configuration.instance()
            palette = config["plotting.palette"]
        if not isinstance(palette, Palette):
            palette = palettes[palette]
        self._palette = palette

        if target is None:
            self._need_tmpfile = True
            self._surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \
                int(self.bbox.width), int(self.bbox.height))
        elif isinstance(target, cairo.Surface):
            self._surface = target
        else:
            self._filename = target
            _, ext = os.path.splitext(target)
            ext = ext.lower()
            if ext == ".pdf":
                self._surface = cairo.PDFSurface(target, self.bbox.width, \
                                                 self.bbox.height)
            elif ext == ".ps":
                self._surface = cairo.PSSurface(target, self.bbox.width, \
                                                self.bbox.height)
            elif ext == ".png":
                self._surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, \
                    int(self.bbox.width), int(self.bbox.height))
            elif ext == ".svg":
                self._surface = cairo.SVGSurface(target, self.bbox.width, \
                                                 self.bbox.height)
            else:
                raise ValueError("image format not handled by Cairo: %s" % ext)

        self._ctx = cairo.Context(self._surface)
        self._objects = []
        self._is_dirty = False

        self.background = background
示例#20
0
def main(argv):

    if len(argv) < 1:
        usage()
        sys.exit(1)

    read_point_configs()

    dt_re = re.compile('(.*)\.bag')

    # Make one, flat list of paths to log files
    bag_paths = []

    for path_arg in argv:
        bag_paths.extend(glob.glob(path_arg))

    for bag_path in bag_paths:
        print("Reading {0}".format(bag_path))

        bag = None
        try:
            bag = rosbag.Bag(bag_path)
        except:
            print("Couldn't open {0} for reading!".format(bag_path))
            continue

        bag_filename = os.path.basename(bag_path)
        (map, start_config, mechanism, task_file, remainder) = bag_filename.split('__')
        
        # Create a Cairo surface and get a handle to its context
        surface = cairo.ImageSurface (cairo.FORMAT_ARGB32, IMG_WIDTH, IMG_HEIGHT)
        ctx = cairo.Context (surface)

        # Invert the y-axis to make life easier
        ctx.transform( cairo.Matrix( yy = -1, y0 = IMG_HEIGHT ) )
    
        ctx.scale( IMG_WIDTH, IMG_HEIGHT)

        # Paint a white background
        ctx.set_source_rgb( 1.0, 1.0, 1.0 )
        ctx.rectangle( 0, 0, 1.0, 1.0 )
        ctx.fill()

        draw_arena(ctx)

        # Draw start locations
        for i, start_loc in enumerate(start_locations[start_config]):
            start_loc_x = start_loc[0]
            start_loc_y = start_loc[1]

            # E.g., "robot-1"
            stroke_color = stroke_colors["robot_%d" % (i+1)]

            ctx.set_source_rgb( stroke_color[0], stroke_color[1], stroke_color[2] )
            ctx.rectangle((start_loc_x-6) / IMG_WIDTH,
                          (start_loc_y-6) / IMG_HEIGHT,
                          12. / IMG_WIDTH, 12. / IMG_HEIGHT)
            ctx.stroke()

        # Reset pen to black
        ctx.set_source_rgb(0, 0, 0)
         
        # Draw task points
        task_points = task_point_configs[task_file]

        # Font style for printing points
        ctx.select_font_face('Sans', cairo.FONT_SLANT_NORMAL,
                             cairo.FONT_WEIGHT_BOLD)
        ctx.set_font_size(14. / IMG_WIDTH)

        ctx.set_line_width( ( 1. / IMG_WIDTH ) )

        for i, task_point in enumerate(task_points):
            task_x = task_point[0]
            task_y = task_point[1]

#            print "Drawing task point at (%f,%f)" % (task_x, task_y)

            # Draw point number (i) as a label slightly above and to the right of the point
            ctx.move_to( (task_x+6) / IMG_WIDTH, (task_y+6) / IMG_HEIGHT )
            ctx.transform( cairo.Matrix( yy = -1, y0 = IMG_HEIGHT ) )
            ctx.show_text(str(i+1))
            ctx.stroke()
            ctx.transform( cairo.Matrix( yy = -1, y0 = IMG_HEIGHT ) )

#            ctx.arc(task_x / IMG_WIDTH, task_y / IMG_HEIGHT, 5./IMG_WIDTH, 0, 2*math.pi)
#            ctx.stroke()
#            ctx.fill()
            ctx.move_to( (task_x-5) / IMG_WIDTH, (task_y-5) / IMG_HEIGHT )
            ctx.line_to( (task_x+5) / IMG_WIDTH, (task_y+5) / IMG_HEIGHT )
            ctx.stroke()

            ctx.move_to( (task_x-5) / IMG_WIDTH, (task_y+5) / IMG_HEIGHT )
            ctx.line_to( (task_x+5) / IMG_WIDTH, (task_y-5) / IMG_HEIGHT )
            ctx.stroke()

        # Trajectory line width
        ctx.set_line_width( ( 2. / IMG_WIDTH ) )
    
        run_msgs = defaultdict(list)

        for topic,msg,msg_time in bag.read_messages():
            run_msgs[topic].append(msg)

        for r_name in robot_names:

            # Stroke color
            stroke_color = stroke_colors[r_name]
            ctx.set_source_rgb( stroke_color[0], stroke_color[1], stroke_color[2] )
        
            start_pose = None
            for amcl_msg in run_msgs['/{0}/amcl_pose'.format(r_name)]:
                amcl_pose = amcl_msg.pose.pose
                pose_x = amcl_pose.position.x
                pose_y = amcl_pose.position.y

                if pose_x == 0 and pose_y == 0:
                    continue

                if start_pose is None:
                    ctx.move_to( pose_x * 100. / IMG_WIDTH, pose_y * 100. / IMG_HEIGHT )
                    start_pose = amcl_pose
                    #print "{0} start_pose: {1}:".format(r_name, start_pose)
                else:
                    ctx.line_to( pose_x * 100. / IMG_WIDTH, pose_y * 100. / IMG_HEIGHT)
                
            ctx.stroke()
            
        bag_basename = bag_filename.replace('.bag', '')
        surface.write_to_png( bag_basename + '.png' )
示例#21
0
    def render_image(self, data, output_filename):
        """Render an image for the given player id."""

        # setup variables

        player = data.player
        elos = data.elos
        ranks = data.ranks
        #games           = data.total_stats['games']
        wins, losses = data.total_stats['wins'], data.total_stats['losses']
        games = wins + losses
        kills, deaths = data.total_stats['kills'], data.total_stats['deaths']
        alivetime = data.total_stats['alivetime']

        # build image

        surf = C.ImageSurface(C.FORMAT_ARGB32, self.width, self.height)
        ctx = C.Context(surf)
        self.ctx = ctx
        ctx.set_antialias(C.ANTIALIAS_GRAY)

        # draw background
        if self.bg == None:
            if self.bgcolor != None:
                # plain fillcolor, full transparency possible with (1,1,1,0)
                ctx.save()
                ctx.set_operator(C.OPERATOR_SOURCE)
                ctx.rectangle(0, 0, self.width, self.height)
                ctx.set_source_rgba(self.bgcolor[0], self.bgcolor[1],
                                    self.bgcolor[2], self.bgcolor[3])
                ctx.fill()
                ctx.restore()
        else:
            try:
                # background texture
                bg = C.ImageSurface.create_from_png("img/%s.png" % self.bg)

                # tile image
                if bg:
                    bg_w, bg_h = bg.get_width(), bg.get_height()
                    bg_xoff = 0
                    while bg_xoff < self.width:
                        bg_yoff = 0
                        while bg_yoff < self.height:
                            ctx.set_source_surface(bg, bg_xoff, bg_yoff)
                            #ctx.mask_surface(bg)
                            ctx.paint()
                            bg_yoff += bg_h
                        bg_xoff += bg_w
            except:
                #print "Error: Can't load background texture: %s" % self.bg
                pass

        # draw overlay graphic
        if self.overlay != None:
            try:
                overlay = C.ImageSurface.create_from_png("img/%s.png" %
                                                         self.overlay)
                ctx.set_source_surface(overlay, 0, 0)
                #ctx.mask_surface(overlay)
                ctx.paint()
            except:
                #print "Error: Can't load overlay texture: %s" % self.overlay
                pass

        ## draw player's nickname with fancy colors

        # deocde nick, strip all weird-looking characters
        qstr = qfont_decode(player.nick).replace('^^',
                                                 '^').replace(u'\x00', '')
        chars = []
        for c in qstr:
            # replace weird characters that make problems - TODO
            if ord(c) < 128:
                chars.append(c)
        qstr = ''.join(chars)
        stripped_nick = strip_colors(qstr.replace(' ', '_'))

        # fontsize is reduced if width gets too large
        ctx.select_font_face(self.font, C.FONT_SLANT_NORMAL,
                             C.FONT_WEIGHT_NORMAL)
        shrinknick = 0
        while shrinknick < 0.6 * self.nick_fontsize:
            ctx.set_font_size(self.nick_fontsize - shrinknick)
            xoff, yoff, tw, th = ctx.text_extents(stripped_nick)[:4]
            if tw > self.nick_maxwidth:
                shrinknick += 1
                continue
            break

        # determine width of single whitespace for later use
        xoff, yoff, tw, th = ctx.text_extents("_")[:4]
        space_w = tw

        # split nick into colored segments
        xoffset = 0
        _all_colors = re.compile(r'(\^\d|\^x[\dA-Fa-f]{3})')
        parts = _all_colors.split(qstr)
        while len(parts) > 0:
            tag = None
            txt = parts[0]
            if _all_colors.match(txt):
                tag = txt[1:]  # strip leading '^'
                if len(parts) < 2:
                    break
                txt = parts[1]
                del parts[1]
            del parts[0]

            if not txt or len(txt) == 0:
                # only colorcode and no real text, skip this
                continue

            if tag:
                if tag.startswith('x'):
                    r = int(tag[1] * 2, 16) / 255.0
                    g = int(tag[2] * 2, 16) / 255.0
                    b = int(tag[3] * 2, 16) / 255.0
                    hue, light, satur = rgb_to_hls(r, g, b)
                    if light < _contrast_threshold:
                        light = _contrast_threshold
                        r, g, b = hls_to_rgb(hue, light, satur)
                else:
                    r, g, b = _dec_colors[int(tag[0])]
            else:
                r, g, b = _dec_colors[7]

            xoff, yoff, tw, th = ctx.text_extents(txt)[:4]
            ctx.set_source_rgb(r, g, b)
            ctx.move_to(self.nick_pos[0] + xoffset - xoff, self.nick_pos[1])
            ctx.show_text(txt)

            tw += (len(txt) -
                   len(txt.strip())) * space_w  # account for lost whitespaces
            xoffset += tw + 2

        ## print elos and ranks

        xoffset, yoffset = 0, 0
        count = 0
        for gt in data.total_stats['gametypes'][:self.num_gametypes]:
            if not elos.has_key(gt) or not ranks.has_key(gt):
                continue
            count += 1

        # re-align segments if less than max. gametypes are shown
        if count > 0:
            if count < self.num_gametypes:
                diff = self.num_gametypes - count
                if diff % 2 == 0:
                    xoffset += (diff - 1) * self.gametype_width
                    yoffset += (diff - 1) * self.gametype_height
                else:
                    xoffset += 0.5 * diff * self.gametype_width
                    yoffset += 0.5 * diff * self.gametype_height

            # show a number gametypes the player has participated in
            for gt in data.total_stats['gametypes'][:self.num_gametypes]:
                if not elos.has_key(gt) or not ranks.has_key(gt):
                    continue

                offset = (xoffset, yoffset)
                if self.gametype_pos:
                    if self.gametype_upper:
                        txt = self.gametype_text % gt.upper()
                    else:
                        txt = self.gametype_text % gt.lower()
                    self.set_font(self.gametype_fontsize,
                                  self.gametype_color,
                                  bold=True)
                    self.show_text(txt,
                                   self.gametype_pos,
                                   self.gametype_align,
                                   offset=offset)

                if self.elo_pos:
                    txt = self.elo_text % round(elos[gt], 0)
                    self.set_font(self.elo_fontsize, self.elo_color)
                    self.show_text(txt,
                                   self.elo_pos,
                                   self.elo_align,
                                   offset=offset)
                if self.rank_pos:
                    txt = self.rank_text % ranks[gt]
                    self.set_font(self.rank_fontsize, self.rank_color)
                    self.show_text(txt,
                                   self.rank_pos,
                                   self.rank_align,
                                   offset=offset)

                xoffset += self.gametype_width
                yoffset += self.gametype_height
        else:
            if self.nostats_pos:
                xoffset += (self.num_gametypes - 2) * self.gametype_width
                yoffset += (self.num_gametypes - 2) * self.gametype_height
                offset = (xoffset, yoffset)

                txt = self.nostats_text
                self.set_font(self.nostats_fontsize,
                              self.nostats_color,
                              bold=True)
                self.show_text(txt,
                               self.nostats_pos,
                               self.nostats_align,
                               angle=self.nostats_angle,
                               offset=offset)

        # print win percentage

        if self.wintext_pos:
            txt = self.wintext_text
            self.set_font(self.wintext_fontsize, self.wintext_color)
            self.show_text(txt, self.wintext_pos, self.wintext_align)

        txt = "???"
        try:
            ratio = float(wins) / games
            txt = "%.2f%%" % round(ratio * 100, 2)
        except:
            ratio = 0

        if self.winp_pos:
            if ratio >= 0.5:
                nr = 2 * (ratio - 0.5)
                r = nr * self.winp_colortop[0] + (1 -
                                                  nr) * self.winp_colormid[0]
                g = nr * self.winp_colortop[1] + (1 -
                                                  nr) * self.winp_colormid[1]
                b = nr * self.winp_colortop[2] + (1 -
                                                  nr) * self.winp_colormid[2]
            else:
                nr = 2 * ratio
                r = nr * self.winp_colormid[0] + (1 -
                                                  nr) * self.winp_colorbot[0]
                g = nr * self.winp_colormid[1] + (1 -
                                                  nr) * self.winp_colorbot[1]
                b = nr * self.winp_colormid[2] + (1 -
                                                  nr) * self.winp_colorbot[2]
            self.set_font(self.winp_fontsize, (r, g, b), bold=True)
            self.show_text(txt, self.winp_pos, self.winp_align)

        if self.wins_pos:
            txt = "%d win" % wins
            if wins != 1:
                txt += "s"
            self.set_font(self.wins_fontsize, self.wins_color)
            self.show_text(txt, self.wins_pos, self.wins_align)

        if self.loss_pos:
            txt = "%d loss" % losses
            if losses != 1:
                txt += "es"
            self.set_font(self.loss_fontsize, self.loss_color)
            self.show_text(txt, self.loss_pos, self.loss_align)

        # print kill/death ratio

        if self.kdtext_pos:
            txt = self.kdtext_text
            self.set_font(self.kdtext_fontsize, self.kdtext_color)
            self.show_text(txt, self.kdtext_pos, self.kdtext_align)

        txt = "???"
        try:
            ratio = float(kills) / deaths
            txt = "%.3f" % round(ratio, 3)
        except:
            ratio = 0

        if self.kdr_pos:
            if ratio >= 1.0:
                nr = ratio - 1.0
                if nr > 1:
                    nr = 1
                r = nr * self.kdr_colortop[0] + (1 - nr) * self.kdr_colormid[0]
                g = nr * self.kdr_colortop[1] + (1 - nr) * self.kdr_colormid[1]
                b = nr * self.kdr_colortop[2] + (1 - nr) * self.kdr_colormid[2]
            else:
                nr = ratio
                r = nr * self.kdr_colormid[0] + (1 - nr) * self.kdr_colorbot[0]
                g = nr * self.kdr_colormid[1] + (1 - nr) * self.kdr_colorbot[1]
                b = nr * self.kdr_colormid[2] + (1 - nr) * self.kdr_colorbot[2]
            self.set_font(self.kdr_fontsize, (r, g, b), bold=True)
            self.show_text(txt, self.kdr_pos, self.kdr_align)

        if self.kills_pos:
            txt = "%d kill" % kills
            if kills != 1:
                txt += "s"
            self.set_font(self.kills_fontsize, self.kills_color)
            self.show_text(txt, self.kills_pos, self.kills_align)

        if self.deaths_pos:
            txt = ""
            if deaths is not None:
                txt = "%d death" % deaths
                if deaths != 1:
                    txt += "s"
            self.set_font(self.deaths_fontsize, self.deaths_color)
            self.show_text(txt, self.deaths_pos, self.deaths_align)

        # print playing time

        if self.ptime_pos:
            txt = self.ptime_text % str(alivetime)
            self.set_font(self.ptime_fontsize, self.ptime_color)
            self.show_text(txt, self.ptime_pos, self.ptime_align)

        # save to PNG
        #surf.write_to_png(output_filename)
        surf.flush()
        imgdata = surf.get_data()
        write_png(output_filename, imgdata, self.width, self.height)
示例#22
0
def draw_dictionary(d, lookup_paths=None, show_dummy=False):
    """Supply `d` a Python dictionary."""
    global cr

    o = _dictinfo.dictobject(d)

    WIDTH = 960
    if len(o) == 8:
        HEIGHT = 406
    else:
        HEIGHT = 480

    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
    cr = cairo.Context(surface)

    cr.select_font_face('Inconsolata', cairo.FONT_SLANT_NORMAL,
                        cairo.FONT_WEIGHT_BOLD)

    cr.rectangle(0, 0, WIDTH, HEIGHT)
    cr.set_source_rgb(1, 1, 1)
    cr.fill()

    with save(cr):

        mask = o.ma_mask
        sigbits = 0
        while mask:
            sigbits += 1
            mask >>= 1

        if len(o) == 8:
            xoffset = 140
            hashwidth = 9  # width of the hash field
            font_size = 40
            gap = 2
            show_value = True
        else:
            if len(o) == 32:
                xoffset = 360
                hashwidth = 16  # width of the hash field
                show_value = True
                font_size = 12
            else:
                xoffset = 140
                hashwidth = sigbits + 1  # width of the hash field
                show_value = False
                font_size = 10

            gap = 0

        yoffset = font_size  # room for header at top

        cr.set_font_size(font_size)
        charwidth = cr.text_extents(u'M')[2]
        width = 100  #actually compute from font size later

        cr.translate(xoffset, yoffset)  # upper-left corner of the dictionary

        with save(cr):
            cr.set_source_rgb(0, 0, 0)
            cr.translate(2, -6)
            if len(o) == 8:
                cr.show_text(u'Idx      Hash     Key   Value')

        height = 0

        for i in range(len(o)):
            if i == 0 or i % 32:
                cr.rel_move_to(0, height + gap)
            else:
                cr.rel_move_to(176, -31 * height + -30 * gap)

            with save(cr):
                entry = o.ma_table[i]

                height = draw_textbox([gold, bits(i)[-sigbits:]], gray)
                cr.rel_move_to(gap, 0)

                try:
                    k = entry.me_key
                except ValueError:
                    # This is a completely empty entry.
                    draw_textbox([white, u' '], lightgray)
                    cr.rel_move_to(gap, 0)
                    draw_textbox([white, u' ' * hashwidth], lightgray)
                    cr.rel_move_to(gap, 0)
                    draw_textbox([white, u' ' * 7], lightgray)
                    if show_value:
                        cr.rel_move_to(gap, 0)
                        draw_textbox([white, u' ' * 6], lightgray)
                    continue

                if k is _dictinfo.dummy:
                    if not show_dummy:
                        draw_textbox([white, u'!'], red)
                        cr.rel_move_to(gap, 0)
                        draw_textbox([white, u' ' * hashwidth], gray)
                        cr.rel_move_to(gap, 0)
                        draw_textbox([white, u'<dummy>'], gray)
                        if show_value:
                            cr.rel_move_to(gap, 0)
                            draw_textbox([white, u' ' * 6], gray)
                    else:
                        draw_textbox([white, u' '], black)
                        cr.rel_move_to(gap, 0)
                        draw_textbox([white, u' ' * hashwidth], black)
                        cr.rel_move_to(gap, 0)
                        draw_textbox([white, u' ' * 7], black)
                        if show_value:
                            cr.rel_move_to(gap, 0)
                            draw_textbox([white, u' ' * 6], black)
                    continue

                h = entry.me_hash
                v = entry.me_value

                if h & o.ma_mask == i:
                    draw_textbox([white, u'='], green)
                else:
                    draw_textbox([white, u'/'], red)
                cr.rel_move_to(gap, 0)
                bstr = bits(h)[-hashwidth + 1:]
                texts = [
                    lightgray, u'…' + bstr[:-sigbits], gold, bstr[-sigbits:]
                ]
                draw_textbox(texts, gray)
                cr.rel_move_to(gap, 0)
                draw_textbox([white, u'%-7s' % myrepr(k)], gray)
                if show_value:
                    cr.rel_move_to(gap, 0)
                    draw_textbox([white, u'%-6s' % myrepr(v)], gray)

    if lookup_paths is None:
        lookup_paths = ()
    else:
        lookup_paths = (lookup_paths, )
    for lookup_path in lookup_paths:
        with save(cr):
            n = lookup_path[0]
            cr.translate(xoffset, yoffset)

            y = 2 + n * (height + gap + 0.5) + height / 2
            cr.set_source_rgb(*black)
            cr.set_line_width(6)
            cr.move_to(-100, y)
            cr.rel_line_to(40, 0)
            cr.stroke()
            draw_arrowhead(-60, y)

            draw_button(cr, -20, y, len(lookup_path) > 1)

            if len(lookup_path) > 1:
                cr.move_to(650, y)
                cr.rel_line_to(40, 0)
                cr.stroke()

            for i in range(1, len(lookup_path)):
                from_slot = lookup_path[i - 1]
                dest_slot = lookup_path[i]

                yf = 2 + from_slot * (height + gap + 0.5) + height / 2
                yd = 2 + dest_slot * (height + gap + 0.5) + height / 2
                y0 = min(yf, yd)
                y1 = max(yf, yd)

                cr.set_source_rgb(*black)
                cr.set_line_width(6)
                cr.move_to(690, y0)
                cr.arc(690, (y0 + y1) / 2, (y1 - y0) / 2, 3 * pi / 2, pi / 2)
                cr.stroke()

                draw_button(cr, 652, yd, i + 1 < len(lookup_path))

                with save(cr):
                    cr.translate(690, yd)
                    cr.rotate(pi)
                    draw_arrowhead(0, 0)

    return surface
示例#23
0
        context.set_source_rgb(1, 1, 1)
        context.arc(*self.center, self.radius, 0, 2 * math.pi)
        if self.fill:
            context.fill()
        else:
            context.stroke()

    def bind_body(self, body):
        self.parent_body = body

def clear_screen(context):
    context.set_source_rgb(0, 0, 0)
    context.rectangle(0, 0, 1000, 1000)
    context.fill()

surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 1000, 1000)
context = cairo.Context(surface)

FRAME_COUNT = 100

bodies = {
    'blackhole': CelestialBody(125, 0,   (500, 500), False),
    'planet':    CelestialBody(25,  300, (500, 500), True),
    'moon':      CelestialBody(5,   50,  (750, 500), False) }

bodies['planet'].bind_body(bodies['blackhole'])
bodies['moon']  .bind_body(bodies['planet'])

for i in range(FRAME_COUNT):
    clear_screen(context)
示例#24
0
def analyze_searches(request):
    import cairo
    from pycha.pie import PieChart

    results = {}
    sf = initialize_search_form(request)
    for field_name, field in sf.fields.items():
        if isinstance(field, ClassChoiceField) or isinstance(
                field, CustomChoiceField):
            results[field] = {'data': {}, 'meta': {'total': 0}}

    srs = SearchRegistry.objects.filter(date__gte=date.today() -
                                        timedelta(days=7))
    num_queries = len(srs)

    folder = settings.MEDIA_ROOT + '/temp/'
    for the_file in os.listdir(folder):
        file_path = os.path.join(folder, the_file)
        try:
            if os.path.isfile(file_path):
                os.unlink(file_path)
        except:
            pass

    for sr in srs:
        key_vals = sr.query.split('&')
        for key_val in key_vals:
            vals = key_val.split('=')
            field_name = vals[0]
            field = sf.fields[field_name]
            if not (isinstance(field, ClassChoiceField)
                    or isinstance(field, CustomChoiceField)):
                continue

            val = vals[1]
            str_val = field.get_object_name(val)
            if str_val not in results[field]['data']:
                results[field]['data'][str_val] = [0, 0]
            results[field]['data'][str_val][0] += 1
            results[field]['meta']['total'] += 1

    for field, field_dict in results.items():
        try:
            results[field]['meta']['percentage'] = 100.0 * results[field][
                'meta']['total'] / num_queries
        except:
            results[field]['meta']['percentage'] = 0.0
        sub_total = results[field]['meta']['total']
        for field_option, sub_results in field_dict['data'].items():
            sub_results[1] = 100.0 * sub_results[0] / sub_total

        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 600, 400)
        chart = PieChart(surface)

        dataSet = [(field_option, [[0, sub_results[1]]])
                   for field_option, sub_results in field_dict['data'].items()]
        if dataSet:
            chart.addDataset(dataSet)
            chart.render()
            filename = folder + str(
                field.name) + "-" + str(num_queries) + ".png"
            surface.write_to_png(filename)
            results[field]['meta']['is_available'] = True
        else:
            results[field]['meta']['is_available'] = False

    return append_manager_ptype_to_response(request,
                                            'manager/analyze_searches.html', {
                                                'form': sf,
                                                'results': results,
                                                'num_queries': num_queries,
                                            })
示例#25
0
    ctx.set_source_rgb(0.8, 0.8, 0.8)
    ctx.fill_preserve()
    ctx.set_source_rgb(1, 1, 1)
    ctx.stroke()


def input(events):
    for event in events:
        if event.type == pygame.QUIT:
            sys.exit(0)
        else:
            print event


Width, Height = 512, 512
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, Width, Height)

pygame.init()
window = pygame.display.set_mode((Width, Height))
screen = pygame.display.get_surface()

draw(surface)

#Create PyGame surface from Cairo Surface
buf = surface.get_data()
image = pygame.image.frombuffer(
    buf,
    (Width, Height),
    "ARGB",
)
#Tranfer to Screen
示例#26
0
def font_options():
    surface = cairo.ImageSurface(0, 10, 10)
    return surface.get_font_options()
示例#27
0
numcolumns = 0
for line in lines:
	line = line.rstrip('\n')
	vec = line.split(' ')[1:]
	if numcolumns == 0:
		numcolumns = len(vec)
	for v in vec:
		if is_number(v):
			v = int(v)
			if v > maxqueue:
				maxqueue = v
timetotal = len(lines)

WIDTH = min(800, max(400, 1 * timetotal))
HEIGHT = 64 * numcolumns
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx = cairo.Context(surface)
ctx.set_source_rgb(1, 1, 1)
ctx.rectangle(0, 0, WIDTH, HEIGHT)
ctx.fill()

heightdivision = HEIGHT/numcolumns
for i in range(numcolumns-1):
	height = (i + 1) * heightdivision
#ctx.set_source_rgb(0, 0, 0)
#ctx.rectangle(0, height, WIDTH, 1)
#ctx.fill()

widthgap = 10
widthavailable = WIDTH - widthgap
widthdivision = widthavailable/float(timetotal)
示例#28
0
def test_scaled_font_get_font_matrix():
    surface = cairo.ImageSurface(0, 10, 10)
    ctx = cairo.Context(surface)
    sf = ctx.get_scaled_font()
    matrix = sf.get_font_matrix()
    assert isinstance(matrix, cairo.Matrix)
示例#29
0
    def loadFromFile(self,
                     name,
                     w=None,
                     h=None,
                     scale=True,
                     noBackground=False):
        """load icon image to cache or draw the icon with cairo
        TODO: draw all icons through this function ?"""

        # we convert the width and height to int to get rid of some GTK warnings
        w = int(w)
        h = int(h)

        iconPathThemed = self.getCurrentThemePath()
        iconPathDefault = self.getDefaultThemePath()

        (simplePaths, parameterPaths) = self.findUsableIcon(
            name, [iconPathThemed, iconPathDefault])

        parameterPaths.extend(simplePaths)

        image = None
        # is there a filename with positional parameters ?
        if parameterPaths:
            result = None
            aboveTextIconPath = fnmatch.filter(parameterPaths,
                                               "*%s.*" % name).pop()
            pixbufInfo = gtk.gdk.pixbuf_get_file_info(aboveTextIconPath)
            # it we get some info about the file, it means that the image is probably pixbufable
            if pixbufInfo:
                (iconInfo, iconW, iconH) = pixbufInfo
                if iconH == 0:
                    iconH = 1
                hwRatio = iconW / float(iconH)
                border = min(w, h) * 0.1
                targetH = (h * 0.55)
                targetW = w - 2 * border
                # try to fit the icon image above the text inside the icon outline,
                # with some space between, while respecting original aspect ratio"""
                scaledW = targetW
                scaledH = targetW / float(hwRatio)
                if scaledH > targetH:
                    scaledH = targetH
                    scaledW = targetH * hwRatio
                targetX = border + (targetW - scaledW) / 2.0
                targetY = border * 0.9 + ((targetH - scaledH) / 2.0)
                pixbuf = None
                try:
                    # try to load the icon to pixbuf and get its original width and height
                    pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(
                        aboveTextIconPath, int(scaledW), int(scaledH))
                except Exception:
                    self.log.exception("icon %s ir probably corrupted",
                                       aboveTextIconPath)

                if pixbuf:
                    compositeIcon = cairo.ImageSurface(cairo.FORMAT_ARGB32, w,
                                                       h)
                    ct = cairo.Context(compositeIcon)
                    ct2 = gtk.gdk.CairoContext(ct)
                    ct2.set_source_pixbuf(pixbuf, targetX, targetY)
                    ct2.paint()
                    return compositeIcon, True  # this signalizes that a background might be needed
                else:
                    return self.roundedRectangle(
                        w, h, self.buttonFillColor,
                        self.buttonOutlineColor), False
            if result is None:
                return self.roundedRectangle(w, h, self.buttonFillColor,
                                             self.buttonOutlineColor), False
        # just use the classic icon
        elif simplePaths:
            iconPath = simplePaths.pop()
            if scale:
                image = self.getImageSurface(iconPath, w, h)
            else:
                image = self.getImageSurface(iconPath)

        # no icon found
        else:
            self.log.warning("icon %s not found", name)
            # we use the default button background if the tile is missing
            return self.roundedRectangle(w, h, self.buttonFillColor,
                                         self.buttonOutlineColor), False

        if not image:  # loading the image probably failed
            return False
        #    w = float(image.get_width())
        #    h = float(image.get_height())
        return image, False
示例#30
0
]

ttf = addDataPrefix("pieces/ttf")
themes += [
    'ttf-' + splitext(d)[0].capitalize() for d in listdir(ttf)
    if splitext(d)[1] == '.ttf'
]
themes.sort()

for theme in themes:
    pngfile = "%s/%s.png" % (pieces, theme)
    print('Creating %s' % pngfile)

    Pieces.set_piece_theme(theme)

    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, SQUARE * 4, SQUARE * 4)

    context = cairo.Context(surface)
    context.set_source_rgb(0.5, 0.5, 0.5)

    for x in range(4):
        for y in range(4):
            if (x + y) % 2 == 1:
                context.rectangle(x * SQUARE, y * SQUARE, SQUARE, SQUARE)
    context.fill()

    context.rectangle(0, 0, 4 * SQUARE, 4 * SQUARE)
    context.stroke()

    context.set_source_rgb(0, 0, 0)
    for y, row in enumerate(PIECES):