def renegerate_overlay_buffer(self): image = ImageSurface(cairo.FORMAT_ARGB32, self.video_width, self.video_height) context = Context(image) text = "Foo bar 123" font = pango.FontDescription('sans normal 22') text_offset = [6, 6] textOverflowed = False if text: pcContext = pangocairo.CairoContext(context) pangoLayout = pcContext.create_layout() font = pango.FontDescription('sans normal 22') pangoLayout.set_font_description(font) context.move_to(text_offset[0]+2, text_offset[1]+2) pangoLayout.set_markup('<span foreground="black" >%s</span>' % text) pcContext.show_layout(pangoLayout) context.move_to(text_offset[0], text_offset[1]) pangoLayout.set_markup('<span foreground="white" >%s</span>' % text) pcContext.show_layout(pangoLayout) textWidth, textHeight = pangoLayout.get_pixel_size() self.overlay_buffer = image.get_data() print "overlay_buffer size: %d" % len(self.overlay_buffer)
def convert_to_png(input_file, output_file, width=None, height=None): """Convert svg to png.""" if width and height: handle = Rsvg.Handle() svg = handle.new_from_file(input_file) dim = svg.get_dimensions() img = ImageSurface( FORMAT_ARGB32, width, height) ctx = Context(img) ctx.scale(width / dim.width, height / dim.height) svg.render_cairo(ctx) png_io = BytesIO() img.write_to_png(png_io) with open(output_file, 'wb') as fout: fout.write(png_io.getvalue()) fout.close() svg.close() png_io.close() img.finish() else: with open(input_file, "r") as content_file: svg = content_file.read() content_file.close() fout = open(output_file, "wb") svg2png(bytestring=bytes(svg, "UTF-8"), write_to=fout) fout.close()
def on_draw_camera_drawing_area(self, widget: Gtk.Widget, cr: cairo.Context) -> None: if self.camera_frame is not None: pixbuf = GdkPixbuf.Pixbuf.new_from_data( self.camera_frame.tobytes(), GdkPixbuf.Colorspace.RGB, False, 8, len(self.camera_frame[0]), len(self.camera_frame), 3 * len(self.camera_frame[0]), ) available_width = self.camera_drawing_area.get_allocated_width() available_height = self.camera_drawing_area.get_allocated_height() width = float(pixbuf.get_width()) height = float(pixbuf.get_height()) scale = min(available_width / width, available_height / height) if scale < 1: pixbuf = pixbuf.scale_simple(width * scale, height * scale, GdkPixbuf.InterpType.TILES) else: pixbuf = pixbuf.scale_simple(width * scale, height * scale, GdkPixbuf.InterpType.NEAREST) Gdk.cairo_set_source_pixbuf( cr, pixbuf, available_width / 2 - width * scale / 2, available_height / 2 - height * scale / 2, ) cr.paint()
def layout(self, context: cairo.Context): super().layout(context) context.set_font_size(self.font_size) xb, yb, w, h, xa, ya = context.text_extents(self.title) font_shape = Rectangle(Point(h/2 + self.distance, self.distance), xa, h) self.__title_start_point = Point(font_shape.start.x, font_shape.start.y + h) outer_font_box = DrawableRectangle( Point(font_shape.start.x - self.distance, font_shape.start.y - self.distance), font_shape.width + 2 * self.distance, font_shape.height + 2 * self.distance ) self.__outer_font_box = outer_font_box wrapper_shape = DrawableRectangle( Point(0, outer_font_box.start.y + outer_font_box.height / 2), outer_font_box.start.x + max( outer_font_box.width, self.widget.shape.width ) + self.distance, outer_font_box.height/2 + 2*self.distance + self.widget.shape.height ) self.widget.set_translate( outer_font_box.start.x, outer_font_box.start.y + outer_font_box.height + self.distance ) self.__wrapper_shape = wrapper_shape self.shape = DrawableRectangle( Point(0, 0), wrapper_shape.width, wrapper_shape.start.y + wrapper_shape.height )
def convert_svg2png(infile, outfile, w, h): """ Converts svg files to png using Cairosvg or Inkscape @file_path : String; the svg file absolute path @dest_path : String; the png file absolute path """ if use_inkscape: cmd = Popen(["inkscape", "-z", "-f", infile, "-e", outfile, "-w", str(w), "-h", str(h)], stdout=PIPE, stderr=PIPE) cmd.communicate() else: handle = Rsvg.Handle() svg = handle.new_from_file(infile) dim = svg.get_dimensions() img = ImageSurface(FORMAT_ARGB32, w, h) ctx = Context(img) ctx.scale(w / dim.width, h / dim.height) svg.render_cairo(ctx) png_io = BytesIO() img.write_to_png(png_io) with open(outfile, 'wb') as fout: fout.write(png_io.getvalue()) svg.close() png_io.close() img.finish()
def rotation(ctx: cairo.Context, radians: float): ctx.rotate(radians) try: yield finally: ctx.rotate(-radians)
def draw_stats(self, context: cairo.Context): # Draw sunrise, sunset, AQI icon and values self.draw_icon(context, "rise-set-aqi", (450, 300)) self.draw_text( context, position=(505, 337), text=self.weather.sunrise().astimezone(self.timezone).strftime("%H:%M"), color=BLACK, size=32, ) self.draw_text( context, position=(505, 385), text=self.weather.sunset().astimezone(self.timezone).strftime("%H:%M"), color=BLACK, size=32, ) # Pick AQI text and color aqi = self.weather.aqi() if aqi < 50: color = GREEN elif aqi < 150: color = ORANGE else: color = RED text_width = self.draw_text(context, aqi, size=30, weight="bold", noop=True) self.draw_roundrect(context, 505, 402, text_width + 13, 36, 3) context.set_source_rgb(*color) context.fill() self.draw_text( context, position=(510, 430), text=aqi, color=WHITE, size=30, weight="bold" )
def _append_hand_path(self, cr: cairo.Context, pos: Vector2[float], angle: float, radius: float) -> None: if radius == 0: return cr.move_to(*pos) cr.rel_line_to(radius * math.cos(angle), radius * math.sin(angle))
def layout(self, context: cairo.Context): super().layout(context) context.set_font_size(self.font_size) xb, yb, w, h, xa, ya = context.text_extents(self.title) font_shape = Rectangle(Point(h / 2 + self.distance, self.distance), xa, h) self.__title_start_point = Point(font_shape.start.x, font_shape.start.y + h) outer_font_box = DrawableRectangle( Point(font_shape.start.x - self.distance, font_shape.start.y - self.distance), font_shape.width + 2 * self.distance, font_shape.height + 2 * self.distance) self.__outer_font_box = outer_font_box wrapper_shape = DrawableRectangle( Point(0, outer_font_box.start.y + outer_font_box.height / 2), outer_font_box.start.x + max(outer_font_box.width, self.widget.shape.width) + self.distance, outer_font_box.height / 2 + 2 * self.distance + self.widget.shape.height) self.widget.set_translate( outer_font_box.start.x, outer_font_box.start.y + outer_font_box.height + self.distance) self.__wrapper_shape = wrapper_shape self.shape = DrawableRectangle( Point(0, 0), wrapper_shape.width, wrapper_shape.start.y + wrapper_shape.height)
def on_draw(self, wd, cr: cairo.Context): cr.identity_matrix() cr.set_matrix(self.matrix) self.draw_line_grid(cr) if np.any(self.M): # Test if at least on is zero self.draw_squares(cr)
def connect_line(self, cr: cairo.Context, x0, y0): cr.set_source_rgb(*colors[1]) cr.set_line_width(9e-3) cr.move_to(x0, y0) cr.line_to(*self.mousePos) cr.stroke() cr.stroke()
def this_source(ctx: Context, src): old = ctx.get_source() ctx.set_source(src) try: yield finally: ctx.set_source(old)
def draw(self, ctx: cairo.Context, relative_to=(0, 0)): x, y = self.pos - relative_to pat = self.color.to_pattern(x, y, self.size) with source(ctx, pat): ctx.arc(x, y, self.size, 0, math.tau) ctx.fill()
def on_draw(self, widget: Gtk.Widget, cr: cairo.Context) -> bool: if self.frozen: return False if not self.row.valid(): if self.sig is not None: self.tw.disconnect(self.sig) self.sig = None return False path = self.row.get_path() color = self.stylecontext.get_background_color(Gtk.StateFlags.NORMAL) if not self.columns: self.columns = self.tw.get_columns() assert self.columns is not None for col in self.columns: rect = self.tw.get_background_area(path, col) cr.rectangle(rect.x, rect.y, rect.width, rect.height) cr.clip() cr.set_source_rgba(color.red, color.green, color.blue, 1.0 - self.get_state()) cr.set_operator(cairo.OPERATOR_OVER) cr.paint() return False
def this_source_rgb(ctx: Context, r: float, g: float, b: float): old = ctx.get_source() ctx.set_source_rgb(r, g, b) try: yield finally: ctx.set_source(old)
def convert_to_png(input_file, output_file, width=None, height=None): """Convert svg to png.""" if width and height: handle = Rsvg.Handle() svg = handle.new_from_file(input_file) dim = svg.get_dimensions() img = ImageSurface(FORMAT_ARGB32, width, height) ctx = Context(img) ctx.scale(width / dim.width, height / dim.height) svg.render_cairo(ctx) png_io = BytesIO() img.write_to_png(png_io) with open(output_file, 'wb') as fout: fout.write(png_io.getvalue()) fout.close() svg.close() png_io.close() img.finish() else: with open(input_file, "r") as content_file: svg = content_file.read() content_file.close() fout = open(output_file, "wb") svg2png(bytestring=bytes(svg, "UTF-8"), write_to=fout) fout.close()
def make_text(ctx: cairo.Context, text, fd=default_font): layout = pc.create_layout(ctx) ctx.set_source_rgb(0, 0, 0) layout.set_font_description(fd) layout.set_text(text) return layout
def convert_svg2png(infile, outfile, w, h): """ Converts svg files to png using Cairosvg or Inkscape @file_path : String; the svg file absolute path @dest_path : String; the png file absolute path """ if use_inkscape: p = Popen(["inkscape", "-z", "-f", infile, "-e", outfile, "-w", str(w), "-h", str(h)], stdout=PIPE, stderr=PIPE) output, err = p.communicate() else: handle = Rsvg.Handle() svg = handle.new_from_file(infile) dim = svg.get_dimensions() img = ImageSurface(FORMAT_ARGB32, w, h) ctx = Context(img) ctx.scale(w / dim.width, h / dim.height) svg.render_cairo(ctx) png_io = BytesIO() img.write_to_png(png_io) with open(outfile, 'wb') as fout: fout.write(png_io.getvalue()) svg.close() png_io.close() img.finish()
def translation(ctx: cairo.Context, x: float, y: float): ctx.translate(x, y) try: yield finally: ctx.translate(-x, -y)
def _draw_object_sprite(self, ctx: cairo.Context, obj: SsaObject, x, y): """Draws the sprite for an object""" sprite = self.sprite_provider.get_for_object(obj.object.name, lambda: GLib.idle_add(self._redraw))[0] ctx.translate(x, y) ctx.set_source_surface(sprite) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() ctx.translate(-x, -y)
def on_draw_icon_draw(self, widget: DrawingArea, ctx: cairo.Context): scale = 2 ctx.scale(scale, scale) ctx.set_source_surface(self.icon_surface) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() ctx.scale(1 / scale, 1 / scale) return True
def __missing__(self, zoom): zoomfac = (1 + 2*self._r)*zoom self[zoom] = SVGC = ImageSurface(FORMAT_ARGB32, ceil(zoomfac*self._h), ceil(zoomfac*self._k)) sccr = Context(SVGC) sccr.scale(zoom, zoom) sccr.translate(self._uh, self._uk) self._paint_function(sccr) return SVGC
def hypo_scale(self, cr: cairo.Context, a, b, d=None): if d is None: f = self.d * a - b else: f = d * a - b mat = cairo.Matrix(self.width * f, 0, 0, -self.height * f, self.width / 2, self.height / 2) cr.set_matrix(mat)
def operator(ctx: cairo.Context, op: cairo.Operator): prev_op = ctx.get_operator() ctx.set_operator(op) try: yield finally: ctx.set_operator(prev_op)
def source(ctx: cairo.Context, source: cairo.Pattern): src = ctx.get_source() ctx.set_source(source) try: yield finally: ctx.set_source(src)
def _draw_performer(self, ctx: cairo.Context, performer: SsaPerformer, x, y, w, h): # Label ctx.select_font_face("monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) ctx.set_source_rgb(*COLOR_PERFORMER) ctx.set_font_size(12) ctx.move_to(x - 4, y - 8) ctx.show_text(f'{performer.type}') # Direction arrow self._triangle(ctx, x, y, BPC_TILE_DIM, COLOR_PERFORMER, performer.pos.direction.id)
def draw_background(ctx: cairo.Context, width: int, height: int): # TODO: Add noise/cracks/stains bg_color = RadialGradient([Color(0.84, 0.81, 0.74), Color(0.55, 0.50, 0.36)]) center_x = width / 2 center_y = height / 2 with source(ctx, bg_color.to_pattern(center_x, center_y, center_x)), operator( ctx, cairo.Operator.DARKEN ): ctx.paint()
def draw_icon(self, context: cairo.Context, icon: str, position: Tuple[int, int]): image = cairo.ImageSurface.create_from_png( os.path.join(os.path.dirname(__file__), "icons-7", f"{icon}.png") ) context.save() context.translate(*position) context.set_source_surface(image) context.paint() context.restore()
def create_cairo_font_face_for_file(filename, faceindex=0, loadoptions=0): """ http://cairographics.org/freetypepython """ CAIRO_STATUS_SUCCESS = 0 FT_Err_Ok = 0 # find shared objects _freetype_so = ctypes.CDLL('libfreetype.so.6') _cairo_so = ctypes.CDLL('libcairo.so.2') _cairo_so.cairo_ft_font_face_create_for_ft_face.restype = ctypes.c_void_p _cairo_so.cairo_ft_font_face_create_for_ft_face.argtypes = [ ctypes.c_void_p, ctypes.c_int ] _cairo_so.cairo_set_font_face.argtypes = [ctypes.c_void_p, ctypes.c_void_p] _cairo_so.cairo_font_face_status.argtypes = [ctypes.c_void_p] _cairo_so.cairo_status.argtypes = [ctypes.c_void_p] # initialize freetype _ft_lib = ctypes.c_void_p() if FT_Err_Ok != _freetype_so.FT_Init_FreeType(ctypes.byref(_ft_lib)): raise "Error initialising FreeType library." class PycairoContext(ctypes.Structure): _fields_ = [("PyObject_HEAD", ctypes.c_byte * object.__basicsize__), ("ctx", ctypes.c_void_p), ("base", ctypes.c_void_p)] _surface = ImageSurface(FORMAT_A8, 0, 0) # create freetype face ft_face = ctypes.c_void_p() cairo_ctx = Context(_surface) cairo_t = PycairoContext.from_address(id(cairo_ctx)).ctx _cairo_so.cairo_ft_font_face_create_for_ft_face.restype = ctypes.c_void_p if FT_Err_Ok != _freetype_so.FT_New_Face(_ft_lib, filename, faceindex, ctypes.byref(ft_face)): raise Exception("Error creating FreeType font face for " + filename) # create cairo font face for freetype face cr_face = _cairo_so.cairo_ft_font_face_create_for_ft_face( ft_face, loadoptions) if CAIRO_STATUS_SUCCESS != _cairo_so.cairo_font_face_status(cr_face): raise Exception("Error creating cairo font face for " + filename) _cairo_so.cairo_set_font_face(cairo_t, cr_face) if CAIRO_STATUS_SUCCESS != _cairo_so.cairo_status(cairo_t): raise Exception("Error creating cairo font face for " + filename) face = cairo_ctx.get_font_face() return face
def get_context_for_image(self, zoom): """Creates a temporary cairo context for the image surface :param zoom: The current scaling factor :return: Cairo context to draw on """ cairo_context = Context(self.__image) cairo_context.scale(zoom * self.multiplicator, zoom * self.multiplicator) return cairo_context
def draw(self, wdg, ctx: cairo.Context): ctx.set_antialias(cairo.Antialias.NONE) ctx.scale(self.scale, self.scale) chunks_at_frame = self.animation_context.current()[0] if 0 <= self.chunkidx < len(chunks_at_frame): chunk = chunks_at_frame[self.chunkidx] ctx.set_source_surface(chunk, 0, 0) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint()
def _set_color(context: cairo.Context, color: Tuple) -> None: """set the context color""" if len(color) == 4: red, green, blue, alpha = color context.set_source_rgba(red / 255.0, green / 255.0, blue / 255.0, alpha / 255.0) else: red, green, blue = color context.set_source_rgb(red / 255.0, green / 255.0, blue / 255.0)
def setup_doc(name): ''' ''' doc = PDFSurface(name, sheet_width*ptpin, sheet_height*ptpin) ctx = Context(doc) ctx.scale(ptpin, ptpin) set_font_face_from_file(ctx, 'DejaVuSerifCondensed.ttf') return doc, ctx
def showWrappedText(ctx: cairo.Context, text: str, top=0.0, left=0.0, right=None, lineHeight=12.0): maxWidth = right - left inputLines = text.split('\n') inputWords = [line.split(' ') for line in inputLines] currentOffset = 0 for line in inputWords: currentLine = [] while len(line): nextWord = line.pop(0) nextLine = currentLine + [nextWord] if (ctx.text_extents(' '.join(nextLine)).width > maxWidth): ctx.move_to(left, top + currentOffset) ctx.show_text(' '.join(currentLine)) currentLine = [nextWord] currentOffset = currentOffset + lineHeight else: currentLine = nextLine if (len(currentLine)): ctx.move_to(left, top + currentOffset) ctx.show_text(' '.join(currentLine)) currentOffset = currentOffset + lineHeight * 1.4
def draw_alerts(self, context: cairo.Context): # Load weather alerts alerts = self.weather.active_alerts() for alert in alerts: alert["color"] = RED # Add holidays for holiday_date, holiday_name in holidays.items(): days_until = (holiday_date - datetime.date.today()).days if 0 <= days_until <= 14: alerts.append( { "text": holiday_name, "subtext": ( "in %i days" % days_until if days_until != 1 else "tomorrow" ), "color": BLUE, } ) # Add no alert pill if there weren't any if not alerts: alerts = [{"text": "No Alerts", "color": BLACK}] top = 265 left = 5 for alert in alerts: text = alert["text"].upper() text_width = self.draw_text( context, text, position=(0, 0), size=20, weight="bold", noop=True, ) self.draw_roundrect(context, left, top, text_width + 15, 30, 4) context.set_source_rgb(*alert["color"]) context.fill() left += self.draw_text( context, text, position=(left + 8, top + 23), size=20, color=WHITE, weight="bold", ) if alert.get("subtext"): subtext_width = self.draw_text( context, alert["subtext"], position=(left + 20, top + 26), size=15, color=BLACK, ) else: subtext_width = 0 left += 30 + subtext_width
def create_cairo_font_face_for_file(filename, faceindex=0, loadoptions=0): """ http://cairographics.org/freetypepython """ CAIRO_STATUS_SUCCESS = 0 FT_Err_Ok = 0 # find shared objects _freetype_so = ctypes.CDLL('libfreetype.so.6') _cairo_so = ctypes.CDLL('libcairo.so.2') _cairo_so.cairo_ft_font_face_create_for_ft_face.restype = ctypes.c_void_p _cairo_so.cairo_ft_font_face_create_for_ft_face.argtypes = [ ctypes.c_void_p, ctypes.c_int ] _cairo_so.cairo_set_font_face.argtypes = [ ctypes.c_void_p, ctypes.c_void_p ] _cairo_so.cairo_font_face_status.argtypes = [ ctypes.c_void_p ] _cairo_so.cairo_status.argtypes = [ ctypes.c_void_p ] # initialize freetype _ft_lib = ctypes.c_void_p() if FT_Err_Ok != _freetype_so.FT_Init_FreeType(ctypes.byref(_ft_lib)): raise "Error initialising FreeType library." class PycairoContext(ctypes.Structure): _fields_ = [("PyObject_HEAD", ctypes.c_byte * object.__basicsize__), ("ctx", ctypes.c_void_p), ("base", ctypes.c_void_p)] _surface = ImageSurface(FORMAT_A8, 0, 0) # create freetype face ft_face = ctypes.c_void_p() cairo_ctx = Context(_surface) cairo_t = PycairoContext.from_address(id(cairo_ctx)).ctx _cairo_so.cairo_ft_font_face_create_for_ft_face.restype = ctypes.c_void_p if FT_Err_Ok != _freetype_so.FT_New_Face(_ft_lib, filename, faceindex, ctypes.byref(ft_face)): raise Exception("Error creating FreeType font face for " + filename) # create cairo font face for freetype face cr_face = _cairo_so.cairo_ft_font_face_create_for_ft_face(ft_face, loadoptions) if CAIRO_STATUS_SUCCESS != _cairo_so.cairo_font_face_status(cr_face): raise Exception("Error creating cairo font face for " + filename) _cairo_so.cairo_set_font_face(cairo_t, cr_face) if CAIRO_STATUS_SUCCESS != _cairo_so.cairo_status(cairo_t): raise Exception("Error creating cairo font face for " + filename) face = cairo_ctx.get_font_face() return face
def on_draw(self, widget: Widget, context: cairo.Context): for child in self.list: if child.visible: context.save() context.transform(child.fromWidgetCoords) if child.is_clip_set(): rectangle = child.clip_rectangle context.rectangle(rectangle.start.x,rectangle.start.y, rectangle.width,rectangle.height) context.clip() child.on_draw(self,context) context.restore()
def illustrate(self, surface): if self.art != None: illustration = Context(surface) illustration.scale(0.6, 0.6) illustration.translate(self.w / 6, self.h / 6) self.art.render_cairo(illustration) illustration.translate(self.w * 4 / 3, self.h * 4 / 3) illustration.rotate(pi) self.art.render_cairo(illustration)
def on_draw(self, widget: Widget, context: cairo.Context): self.shape.draw_on_context(context) context.set_source_rgb(*global_constants.background) context.fill_preserve() context.set_source_rgb(0, 0, 0) context.stroke() super().on_draw(widget, context)
def set_shape_from_context(self, context: cairo.Context): label = self.label padding = self.padding context.set_font_size(self.font_size) xb, yb, w, h, xa, ya = context.text_extents(label) width = padding * 2 + xa height = padding * 2 + h height = max(height, self.min_height) if self.origin == self.LEFT: start = Point(0, 0) elif self.origin == self.CENTER: start = Point(-width/2, 0) else: start = Point(-width, 0) self.shape = DrawableRoundedRectangle(start, width, height)
def _scale_down(self, handle, ratio): xsize, ysize = self.size if ratio >= 1.0: # Convert surface = ImageSurface(FORMAT_ARGB32, xsize, ysize) ctx = Context(surface) else: # Scale xsize, ysize = int(xsize * ratio), int(ysize * ratio) surface = ImageSurface(FORMAT_ARGB32, xsize, ysize) ctx = Context(surface) ctx.scale(ratio, ratio) # Render handle.render_cairo(ctx) # Transform to a PIL image for further manipulation size = (xsize, ysize) im = frombuffer('RGBA', size, surface.get_data(), 'raw', 'BGRA', 0, 1) surface.finish() return im, xsize, ysize
def glyphs(*args, **kwargs): options = Options(infname='data/vorttest.txt', saveas='output/part1/', outfname='vorttest.png', scale=100., seed_num=20, stepsize=.01, steps=5, directions=1, norm=False, line_width=.5) options.update(kwargs) print >> log, options.infname if not path.exists(options.saveas): os.makedirs(options.saveas) (xmin, ymin), (xmax, ymax), uv = read2vecs(options.infname) width, height = xmax - xmin, ymax - ymin def index2world(points, xmin=xmin, ymin=ymin, scale=options.scale, debug=False): if debug: print "index2world:", print xscale, yscale, points.dtype if debug: print points, points[:,0] -= xmin if debug: print points, points[:,1] -= ymin if debug: print points, points *= scale if debug: print points if 'seed' in options: seed = options.seed else: seed = product(np.linspace(xmin, xmax, num=options.seed_num), np.linspace(ymin, ymax, num=options.seed_num)) ctx = Context(ImageSurface(cairo.FORMAT_ARGB32, int(options.scale * width), int(options.scale * height))) ctx.set_source_rgba(0,0,0) ctx.set_line_width(options.line_width) for s in seed: points = sline(uv, (xmin, ymin), (xmax, ymax), np.array(s), options.stepsize, options.steps, options.norm, options.directions) print >> log, points index2world(points) print >> log, points draw_arrow(ctx, points, arrowhead_size=2) with open(path.join(options.saveas, options.outfname), 'w') as outf: ctx.get_target().write_to_png(outf)
class MapSurface(object): """wrapper to render the map to svg/png""" def __init__(self, hexmap=None, filename=None, width=None, height=None, size=None): self.hexmap = hexmap if self.hexmap is None: raise ValueError("No map was passed to {}".format(self.__class__.__name__)) self.surface_name = filename or "test.svg" self.size = size or 32.0 self.surface_width = width if self.surface_width is None: self.surface_width = (self.hexmap.map.cols + .5) * self.size * SQRT3 self.surface_height = height if self.surface_height is None: self.surface_height = (self.hexmap.map.rows * 1.5 + .25) * self.size self.layer = [] # build base map self.surface = SVGSurface(self.surface_name + ".svg", self.surface_width, self.surface_height) self.context = Context(self.surface) # background: magenta self.context.save() self.context.set_source_rgb(1.0, 0.0, 1.0) self.context.paint() self.context.restore() def add_layer(self, renderer_cls, position=None): if not position: self.layer.append(renderer_cls(self)) else: self.layer.insert(position, renderer_cls(self)) def render(self): print "Rendering {} ({}x{})".format(self.surface_name, self.surface_width, self.surface_height) for renderer in self.layer: renderer.render() def finalise(self, with_png=False): print "finalising:" if with_png is True: print "PNG" self.surface.write_to_png(self.surface_name + ".png") print "SVG" self.surface.finish() print "DONE!"
def __init__(self, width, height): self.xform = lambda x, y: (x, y) self.img = ImageSurface(FORMAT_RGB24, width, height) self.ctx = Context(self.img) self.ctx.move_to(0, 0) self.ctx.line_to(width, 0) self.ctx.line_to(width, height) self.ctx.line_to(0, height) self.ctx.line_to(0, 0) self.ctx.set_source_rgb(1, 1, 1) self.ctx.fill() self.width = width self.height = height
def layout(self, context: cairo.Context): if not self.is_shape_set: context.save() context.set_font_size(self.font_size) generator = (context.text_extents(chr(letter) * 10) for letter in range(ord('A'), ord('Z') + 1)) context.restore() sizes = [(xa, h) for xb, yb, w, h, xa, ya in generator] max_height = 0 for w, h in sizes: max_height = max(h, max_height) width = self.width height = self.padding * 3 + max_height self.shape = DrawableRectangle(Point(0, 0), width, height)
def layout(self, context: cairo.Context): context.save() context.set_font_size(self.font_size) generator = (context.text_extents(str(digit) * self.digits) for digit in range(10)) sizes = [(xa, h) for xb, yb, w, h, xa, ya in generator] max_width = 0 max_height = 0 for w, h in sizes: max_width = max(w, max_width) max_height = max(h, max_height) width = self.padding * 2 + max_width height = self.padding * 2 + max_height self.shape = DrawableRectangle(Point(0, 0), width, height) context.restore()
def __init__(self, filename, width, height): """ """ self.filename = filename self.size = width, height handle, dummy_file = mkstemp(prefix='cairoutils-', suffix='.pdf') close(handle) surface = PDFSurface(dummy_file, width, height) self.context = Context(surface) self.commands = [] self.garbage = [dummy_file] self.page = [] self.point = Point(0, 0) self.stack = [(1, 0, 0, 0, -1, height)] self.affine = Affine(*self.stack[0])
def __init__(self, hexmap=None, filename=None, width=None, height=None, size=None): self.hexmap = hexmap if self.hexmap is None: raise ValueError("No map was passed to {}".format(self.__class__.__name__)) self.surface_name = filename or "test.svg" self.size = size or 32.0 self.surface_width = width if self.surface_width is None: self.surface_width = (self.hexmap.map.cols + .5) * self.size * SQRT3 self.surface_height = height if self.surface_height is None: self.surface_height = (self.hexmap.map.rows * 1.5 + .25) * self.size self.layer = [] # build base map self.surface = SVGSurface(self.surface_name + ".svg", self.surface_width, self.surface_height) self.context = Context(self.surface) # background: magenta self.context.save() self.context.set_source_rgb(1.0, 0.0, 1.0) self.context.paint() self.context.restore()
def layout(self, context: cairo.Context): super().layout(context) context.save() self.__plus_button.layout(context) context.restore() self.__minus_button.min_height = self.__plus_button.shape.height context.save() self.__minus_button.layout(context) context.restore() plus_shape = self.__plus_button.shape minus_shape = self.__minus_button.shape self.__minus_button.set_translate(self.padding, self.padding/2) self.__plus_button.set_translate( self.padding + minus_shape.width + self.padding, self.padding/2 ) self.shape = DrawableRectangle( Point(0, 0), plus_shape.width + minus_shape.width + 3 * self.padding, self.padding + max(plus_shape.height, minus_shape.height) )
def main(args, **argv): from dddUtils.ioOBJ import load_2d as load from cairo import SVGSurface, Context from numpy import array from glob import glob prefix = args.prefix size = args.size scale = args.scale one = 1.0/size steps = args.steps stride = args.stride skip = args.skip out = prefix + '.svg' print('making file: {:s}'.format(out)) s = SVGSurface(out, size, size) c = Context(s) c.set_line_width(0.1) c.set_source_rgba(*BLACK) for fn in sorted(glob(prefix + '*.2obj'))[skip:steps:stride]: print(fn) data = load(fn) vertices = data['vertices'] vertices *= scale*size edges = data['edges'] # make_random_line(c, vertices, edges) make_line(c, vertices, edges) c.save() return
def main(args, **argv): # from render.render import Render from dddUtils.ioOBJ import load_2d as load from cairo import SVGSurface, Context from numpy import array size = args.size scale = args.scale one = 1.0/size data = load(args.fn) print(data) vertices = data['vertices'] faces = data['faces'] edges = data['edges'] out = '.'.join(args.fn.split('.')[:-1])+'.svg' print('making file: {:s}'.format(out)) s = SVGSurface(out, size, size) c = Context(s) c.set_line_width(0.1) c.set_source_rgba(*BLACK) vertices -= get_mid(vertices) vertices *= scale vertices += array([[0.5,0.5]]) vertices *= size make_triangles(c, vertices, faces, edges) # make_random_length_strips(c, vertices, faces, edges) c.save() return
def export_svg(fn, paths, w, h, line_width=0.1): from cairo import SVGSurface, Context s = SVGSurface(fn, w, h) c = Context(s) c.set_line_width(line_width) for path in paths: c.new_path() c.move_to(*path[0,:]) for p in path[1:]: c.line_to(*p) c.stroke() c.save()
class FakeContext: """ """ def __init__(self, filename, width, height): """ """ self.filename = filename self.size = width, height handle, dummy_file = mkstemp(prefix='cairoutils-', suffix='.pdf') close(handle) surface = PDFSurface(dummy_file, width, height) self.context = Context(surface) self.commands = [] self.garbage = [dummy_file] self.page = [] self.point = Point(0, 0) self.stack = [(1, 0, 0, 0, -1, height)] self.affine = Affine(*self.stack[0]) def command(self, text, *args): if args: self.page.append((text, args)) else: self.page.append(('raw', [text])) def show_page(self): # vertically flip everything because FPDF. self.commands.append(('AddPage', [])) self.commands.append(('raw', ['1 0 0 -1 0 %.3f cm' % self.size[1]])) self.commands += self.page self.page = [] def finish(self): """ """ info = { 'size': self.size, 'commands': self.commands, 'filename': self.filename } page = Popen(['php', 'lossy/page.php'], stdin=PIPE) json.dump(info, page.stdin) page.stdin.close() page.wait() for filename in self.garbage: unlink(filename) def translate(self, x, y): self.affine = self.affine.translate(x, y) self.point = Point(self.point.x + x, self.point.y + y) self.command('1 0 0 1 %.3f %.3f cm' % (x, y)) def scale(self, x, y): self.affine = self.affine.scale(x, y) self.point = Point(self.point.x * x, self.point.y * y) self.command('%.6f 0 0 %.6f 0 0 cm' % (x, y)) def save(self): self.stack.append(self.affine.terms()) self.command('q') def restore(self): self.affine = Affine(*self.stack.pop()) self.command('Q') def user_to_device(self, x, y): user = Point(x, y) device = self.affine(user) return (device.x, device.y) def device_to_user(self, x, y): device = Point(x, y) user = self.affine.inverse()(device) return (user.x, user.y) def move_to(self, x, y): self.point = Point(x, y) self.command('%.3f %.3f m' % (x, y)) def rel_line_to(self, x, y): end = Point(x, y).add(self.point) self.point = end self.command('%.3f %.3f l' % (end.x, end.y)) def set_source_rgb(self, r, g, b): self.command('%.3f %.3f %.3f rg' % (r, g, b)) def fill(self): self.command('f') def set_source_surface(self, surf, x, y): """ """ dim = surf.get_width(), surf.get_height() img = Image.fromstring('RGBA', dim, surf.get_data()) # weird channel order blue, green, red, alpha = img.split() img = Image.merge('RGB', (red, green, blue)) png_buf = StringIO() img.save(png_buf, 'PNG') jpg_buf = StringIO() img.save(jpg_buf, 'JPEG', quality=75) if len(jpg_buf.getvalue()) < len(png_buf.getvalue()): method, buffer, suffix = 'raw_jpeg', jpg_buf, '.jpg' else: method, buffer, suffix = 'raw_png', png_buf, '.png' handle, filename = mkstemp(prefix='cairoutils-', suffix=suffix) self.command(method, filename) self.garbage.append(filename) write(handle, buffer.getvalue()) close(handle) def paint(self): pass def set_line_width(self, w): self.command('%.3f w' % w) def set_dash(self, a): a = ' '.join(['%.3f' % v for v in a]) self.command('[%s] 0 d' % a) def stroke(self): self.command('S') def rel_curve_to(self, a, b, c, d, e, f): p1 = Point(a, b).add(self.point) p2 = Point(c, d).add(self.point) p3 = Point(e, f).add(self.point) self.point = p3 self.command('%.3f %.3f %.3f %.3f %.3f %.3f c' % (p1.x, p1.y, p2.x, p2.y, p3.x, p3.y)) def set_font_face(self, font): self.context.set_font_face(font) def set_font_size(self, size): self.context.set_font_size(size) # SetFont here because only the size gives a clue to the correct weight self.command('SetFont', 'Liberation Sans', (size > 14) and 'B' or '') self.command('SetFontSize', size) def show_text(self, text): x, y = self.point.x, self.point.y text = text.decode('utf8') # invert the vertical flip in self.show_page() before showing text. self.command('q 1 0 0 -1 0 0 cm BT %.3f %.3f Td (%s) Tj ET Q' % (x, -y, text)) def text_extents(self, text): return self.context.text_extents(text)
ndB = ndarray(shape=(rows,width), buffer=copybuffer, dtype=ubyte, order='C', offset=2, strides=[pitch, 3]) try: ndI = ndarray(shape=(rows,width), buffer=I.get_data(), dtype=uint32, order='C', strides=[I.get_stride(), 4]) except NotImplementedError: raise SystemExit("For python 3.x, you need pycairo >= 1.11+ (from https://github.com/pygobject/pycairo)") # 255 * 2**24 = opaque ndI[:,:] = 255 * 2**24 + ndR[:,:] * 2**16 + ndG[:,:] * 2**8 + ndB[:,:] I.mark_dirty() surface = ImageSurface(FORMAT_ARGB32, 800, 600) ctx = Context(surface) ctx.set_source_surface(I, 0, 0) pattern = ctx.get_source() SurfacePattern.set_filter(pattern, FILTER_BEST) scale = 480.0 / rows scalematrix = Matrix() scalematrix.scale(1.0/scale,1.0/scale) scalematrix.translate(-(400.0 - width *scale /2.0 )+200, -60) pattern.set_matrix(scalematrix) ctx.paint() # we need this later for shifting the taller LCD_V glyph up. rows_old = rows # LCD_V
def make_label(text, filename, size=12, angle=0): ''' Parameters: ----------- text : string Text to be displayed filename : string Path to a font size : int Font size in 1/64th points angle : float Text angle in degrees ''' face = Face(filename) face.set_char_size( size*64 ) # FT_Angle is a 16.16 fixed-point value expressed in degrees. angle = FT_Angle(angle * 65536) matrix = FT_Matrix( FT_Cos( angle ), - FT_Sin( angle ), FT_Sin( angle ) , FT_Cos( angle ) ) flags = FT_LOAD_RENDER pen = FT_Vector(0,0) FT_Set_Transform( face._FT_Face, byref(matrix), byref(pen) ) previous = 0 xmin, xmax = 0, 0 ymin, ymax = 0, 0 for c in text: face.load_char(c, flags) kerning = face.get_kerning(previous, c) previous = c bitmap = face.glyph.bitmap pitch = face.glyph.bitmap.pitch width = face.glyph.bitmap.width rows = face.glyph.bitmap.rows top = face.glyph.bitmap_top left = face.glyph.bitmap_left pen.x += kerning.x x0 = (pen.x >> 6) + left x1 = x0 + width y0 = (pen.y >> 6) - (rows - top) y1 = y0 + rows xmin, xmax = min(xmin, x0), max(xmax, x1) ymin, ymax = min(ymin, y0), max(ymax, y1) pen.x += face.glyph.advance.x pen.y += face.glyph.advance.y L = ImageSurface(FORMAT_A8, xmax-xmin, ymax-ymin) previous = 0 pen.x, pen.y = 0, 0 ctx = Context(L) for c in text: face.load_char(c, flags) kerning = face.get_kerning(previous, c) previous = c bitmap = face.glyph.bitmap pitch = face.glyph.bitmap.pitch width = face.glyph.bitmap.width rows = face.glyph.bitmap.rows top = face.glyph.bitmap_top left = face.glyph.bitmap_left pen.x += kerning.x x = (pen.x >> 6) - xmin + left y = - (pen.y >> 6) + ymax - top if (width > 0): glyph_surface = make_image_surface(face.glyph.bitmap) ctx.set_source_surface(glyph_surface, x, y) ctx.paint() pen.x += face.glyph.advance.x pen.y += face.glyph.advance.y L.flush() return L
ctx.set_source_surface(glyph_surface, x, y) ctx.paint() pen.x += face.glyph.advance.x pen.y += face.glyph.advance.y L.flush() return L if __name__ == '__main__': from PIL import Image n_words = 200 H, W, dpi = 600, 800, 72.0 I = ImageSurface(FORMAT_A8, W, H) ctxI = Context(I) ctxI.rectangle(0,0,800,600) ctxI.set_source_rgba (0.9, 0.9, 0.9, 0) ctxI.fill() S = random.normal(0,1,n_words) S = (S-S.min())/(S.max()-S.min()) S = sort(1-sqrt(S))[::-1] sizes = (12 + S*48).astype(int).tolist() def spiral(): eccentricity = 1.5 radius = 8 step = 0.1 t = 0 while True: t += step
def export_svg(fn, paths, size, line_with=0.1, scale_factor=None): from cairo import SVGSurface, Context from numpy import array from ddd import spatial_sort_2d as sort if not scale_factor: scale_factor = size one = 1.0/size s = SVGSurface(fn, size, size) c = Context(s) c.set_line_width(0.1) paths = sort(paths) for path in paths: path *= scale_factor c.new_path() c.move_to(*path[0,:]) for p in path[1:]: c.line_to(*p) c.stroke() c.save()
STOP, MOVETO, LINETO, CURVE3, CURVE4 = 0, 1, 2, 3, 4 face = Face('./Vera.ttf') face.set_char_size( 48*64 ) face.load_char('S') slot = face.glyph outline = slot.outline points = numpy.array(outline.points, dtype=[('x',float), ('y',float)]) x, y = points['x'], points['y'] cbox = outline.get_cbox() surface = ImageSurface(FORMAT_ARGB32, (cbox.xMax - cbox.xMin)//4 + 20, (cbox.yMax - cbox.yMin)//4 + 20) ctx = Context(surface) ctx.scale(0.25,0.25) ctx.translate(-cbox.xMin + 40,-cbox.yMin + 40) ctx.transform(Matrix(1,0,0,-1)) ctx.translate(0, -(cbox.yMax + cbox.yMin)) # difference! Curve_Tag = [FT_Curve_Tag(tag) for tag in outline.tags] start, end = 0, 0 VERTS, CODES = [], [] # Iterate over each contour ctx.set_source_rgb(0.5,0.5,0.5) for i in range(len(outline.contours)): end = outline.contours[i]
raise RuntimeError('pitch != width * 4 for color bitmap: Please report this.') bitmap = np.array(bitmap.buffer, dtype=np.uint8).reshape((bitmap.rows,bitmap.width,4)) I = ImageSurface(FORMAT_ARGB32, width, rows) try: ndI = np.ndarray(shape=(rows,width), buffer=I.get_data(), dtype=np.uint32, order='C', strides=[I.get_stride(), 4]) except NotImplementedError: raise SystemExit("For python 3.x, you need pycairo >= 1.11+ (from https://github.com/pygobject/pycairo)") # Although both are 32-bit, cairo is host-order while # freetype is small endian. ndI[:,:] = bitmap[:,:,3] * 2**24 + bitmap[:,:,2] * 2**16 + bitmap[:,:,1] * 2**8 + bitmap[:,:,0] I.mark_dirty() surface = ImageSurface(FORMAT_ARGB32, 2*width, rows) ctx = Context(surface) ctx.set_source_surface(I, 0, 0) ctx.paint() ctx.set_source_surface(I, width/2, 0) ctx.paint() ctx.set_source_surface(I, width , 0) ctx.paint() surface.write_to_png("emoji-color-cairo.png") Image.open("emoji-color-cairo.png").show()