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
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)
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
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
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
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
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)
def setUp(self): self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 10, 10) self.context = cairo.Context(self.surface) self.tester = CairoSignalTester()
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)
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())
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
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)
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)
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)
def __init__(self, canvas): self.canvas = canvas self.surface = cairo.ImageSurface(cairo.FORMAT_RGB24, 1, 1) self.ctx = cairo.Context(self.surface)
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
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
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' )
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)
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
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)
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, })
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
def font_options(): surface = cairo.ImageSurface(0, 10, 10) return surface.get_font_options()
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)
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)
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
] 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):