def draw(self, wdg, ctx: cairo.Context, *args): if self.surface: ctx.fill() ctx.set_source_surface(self.surface, 0, 0) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() # Draw rectangles on the WTE image representing the selected WTU entries # Allows multiple selections active_rows: List[Gtk.TreePath] = self.builder.get_object( 'wtu_tree').get_selection().get_selected_rows()[ 1] # type: ignore store: Gtk.ListStore = self.builder.get_object( 'wtu_store') # type: ignore for x in active_rows: row = store[x.get_indices()[0]] ctx.set_line_width(4) ctx.set_source_rgba(1, 1, 1, 1) ctx.rectangle(int(row[0]), int(row[1]), int(row[2]), int(row[3])) ctx.stroke() ctx.set_line_width(2) ctx.set_source_rgba(0, 0, 0, 1) ctx.rectangle(int(row[0]), int(row[1]), int(row[2]), int(row[3])) ctx.stroke() return True
def selection_draw_callback(self, ctx: cairo.Context, x: int, y: int): # Draw a chunk chunks_at_frame = self.animation_context.current()[0] ctx.set_source_surface( chunks_at_frame[self.interaction_chunks_selected_id], x, y) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint()
def draw(self, wdg, ctx: cairo.Context, *args): if self.surface: wdg.set_size_request(self.surface.get_width(), self.surface.get_height()) ctx.fill() ctx.set_source_surface(self.surface, 0, 0) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() entry_tree: Gtk.TreeView = self.builder.get_object('entry_tree') active_rows: List[Gtk.TreePath] = entry_tree.get_selection( ).get_selected_rows()[1] for x in active_rows: prop = self.entries[x.get_indices()[0]].get_properties() if self.font.get_entry_image_size() > 12: ctx.set_line_width(4) ctx.set_source_rgba(0, 0, 0, 1) ctx.rectangle((prop["char"]%16)*self.font.get_entry_image_size()*IMAGE_ZOOM, \ (prop["char"]//16)*self.font.get_entry_image_size()*IMAGE_ZOOM, prop["width"]*IMAGE_ZOOM, self.font.get_entry_image_size()*IMAGE_ZOOM) ctx.stroke() ctx.set_line_width(2) if self.font.get_entry_image_size() > 12: ctx.set_source_rgba(1, 1, 1, 1) else: ctx.set_source_rgba(1, 0, 0, 1) ctx.rectangle((prop["char"]%16)*self.font.get_entry_image_size()*IMAGE_ZOOM, \ (prop["char"]//16)*self.font.get_entry_image_size()*IMAGE_ZOOM, prop["width"]*IMAGE_ZOOM, self.font.get_entry_image_size()*IMAGE_ZOOM) ctx.stroke() return True
def draw(self, wdg, ctx: cairo.Context): ctx.set_antialias(cairo.Antialias.NONE) ctx.scale(self.scale, self.scale) # Background ctx.set_source_rgb(0, 0, 0) ctx.rectangle(0, 0, self.width, self.height) ctx.fill() matrix_x_flip = cairo.Matrix(-1, 0, 0, 1, BPC_TILE_DIM, 0) matrix_y_flip = cairo.Matrix(1, 0, 0, -1, 0, BPC_TILE_DIM) tiles_for_pals = self.animation_context.current() for i, mapping in enumerate(self.tile_mappings): tiles_for_frame = tiles_for_pals[mapping.pal_idx] tile_at_pos = mapping.idx if 0 < tile_at_pos < len(tiles_for_frame): tile = tiles_for_frame[tile_at_pos] if mapping.flip_x: ctx.transform(matrix_x_flip) if mapping.flip_y: ctx.transform(matrix_y_flip) ctx.set_source_surface(tile, 0, 0) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() if mapping.flip_x: ctx.transform(matrix_x_flip) if mapping.flip_y: ctx.transform(matrix_y_flip) if (i + 1) % self.tiling_width == 0: # Move to beginning of next line ctx.translate(-BPC_TILE_DIM * (self.tiling_width - 1), BPC_TILE_DIM) else: # Move to next tile in line ctx.translate(BPC_TILE_DIM, 0)
def draw(self, wdg, ctx: cairo.Context, *args): if self.surface: ctx.fill() ctx.set_source_surface(self.surface, 0, 0) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() return True
def selection_draw_callback(self, ctx: cairo.Context, x: int, y: int): if self.interaction_mode == DrawerInteraction.CHUNKS: # Draw a chunk chunks_at_frame = self.animation_context.current()[self.edited_layer] ctx.set_source_surface( chunks_at_frame[self.interaction_chunks_selected_id], x, y ) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() elif self.interaction_mode == DrawerInteraction.COL: # Draw collision if self.interaction_col_solid: ctx.set_source_rgba(1, 0, 0, 1) ctx.rectangle( x, y, BPC_TILE_DIM, BPC_TILE_DIM ) ctx.fill() elif self.interaction_mode == DrawerInteraction.DAT: # Draw data if self.interaction_dat_value > 0: ctx.select_font_face("monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) ctx.set_font_size(6) ctx.set_source_rgb(1, 1, 1) ctx.move_to(x, y + BPC_TILE_DIM - 2) ctx.show_text(f"{self.interaction_dat_value:02x}")
def on_draw(self, index: int, widget: Gtk.DrawingArea, ctx: cairo.Context): w16 = self._surfaces[index] ctx.set_source_rgb(0, 0, 0) ctx.rectangle(0, 0, *widget.get_size_request()) ctx.fill() ctx.set_source_surface(w16) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint()
def draw(self, wdg, ctx: cairo.Context, *args): if self.surface: wdg.set_size_request(self.surface.get_width(), self.surface.get_height()) ctx.fill() ctx.set_source_surface(self.surface, 0, 0) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() return True
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 _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 draw(self, wdg, ctx: cairo.Context, do_translates=True): ctx.set_antialias(cairo.Antialias.NONE) ctx.scale(self.scale, self.scale) chunk_width = self.tiling_width * DPCI_TILE_DIM chunk_height = self.tiling_height * DPCI_TILE_DIM # Background if not self.use_pink_bg: ctx.set_source_rgb(0, 0, 0) else: ctx.set_source_rgb(1.0, 0, 1.0) ctx.rectangle( 0, 0, self.width_in_chunks * self.tiling_width * DPCI_TILE_DIM, self.height_in_chunks * self.tiling_height * DPCI_TILE_DIM) ctx.fill() # Layers for chunks_at_frame in self.animation_context.current(): for i, chunk_at_pos in enumerate(self.mappings): if 0 < chunk_at_pos < len(chunks_at_frame): chunk = chunks_at_frame[chunk_at_pos] ctx.set_source_surface(chunk, 0, 0) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() if (i + 1) % self.width_in_chunks == 0: # Move to beginning of next line if do_translates: ctx.translate( -chunk_width * (self.width_in_chunks - 1), chunk_height) else: # Move to next tile in line if do_translates: ctx.translate(chunk_width, 0) # Move back to beginning if do_translates: ctx.translate(0, -chunk_height * self.height_in_chunks) break size_w, size_h = self.draw_area.get_size_request() size_w /= self.scale size_h /= self.scale # Selection self.selection_plugin.set_size(self.tiling_width * DPCI_TILE_DIM, self.tiling_height * DPCI_TILE_DIM) self.selection_plugin.draw(ctx, size_w, size_h, self.mouse_x, self.mouse_y) # Tile Grid if self.draw_tile_grid: self.tile_grid_plugin.draw(ctx, size_w, size_h, self.mouse_x, self.mouse_y) # Chunk Grid if self.draw_chunk_grid: self.chunk_grid_plugin.draw(ctx, size_w, size_h, self.mouse_x, self.mouse_y) return True
def on_draw_example_placeholder_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context): sprite, x, y, w, h = self._sprite_provider.get_actor_placeholder( 9999, 0, lambda: GLib.idle_add(lambda: self.builder.get_object('draw_example_placeholder').queue_draw()) # type: ignore ) ctx.set_source_surface(sprite) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() if widget.get_size_request() != (w, h): widget.set_size_request(w, h)
def _surface_place_actor(self, ctx: cairo.Context, x, y, w, h): ctx.set_line_width(1) sprite_surface = self.sprite_provider.get_monster_outline(1, 1)[0] ctx.translate(x, y) ctx.set_source_surface(sprite_surface) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() self._draw_plus(ctx) ctx.translate(-x, -y)
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 on_draw_sprite_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context): scale = 2 sprite, x, y, w, h = self._sprite_provider.get_for_item(self.item_p, lambda: GLib.idle_add(widget.queue_draw)) ctx.scale(scale, scale) ctx.set_source_surface(sprite) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() ctx.scale(1 / scale, 1 / scale) if widget.get_size_request() != (w, h): widget.set_size_request(w * scale, h * scale) return True
def on_draw_sprite_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context): if self.entry.entid > 0: sprite, x, y, w, h = self._sprite_provider.get_monster(self.entry.md_index, 0, lambda: GLib.idle_add(widget.queue_draw)) else: sprite, x, y, w, h = self._sprite_provider.get_error() ctx.set_source_surface(sprite) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() if widget.get_size_request() != (w, h): widget.set_size_request(w, h) return True
def on_draw_portrait_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context): scale = 2 portrait = self._portrait_provider.get(self.entry.md_index - 1, 0, lambda: GLib.idle_add(widget.queue_draw), True) ctx.scale(scale, scale) ctx.set_source_surface(portrait) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() ctx.scale(1 / scale, 1 / scale) if widget.get_size_request() != (IMG_DIM * scale, IMG_DIM * scale): widget.set_size_request(IMG_DIM * scale, IMG_DIM * scale) return True
def on_draw_sprite_draw(self, widget: Gtk.DrawingArea, ctx: cairo.Context): if not self._drawing_is_active: return True scale = 4 sprite, x, y, w, h = self._get_sprite_anim() ctx.scale(scale, scale) ctx.set_source_surface(sprite) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() ww, wh = widget.get_size_request() if ww < w or wh < h: widget.set_size_request(w * scale, h * scale) ctx.scale(1 / scale, 1 / scale) return True
def _draw_actor_sprite(self, ctx: cairo.Context, actor: SsaActor, x, y): """Draws the sprite for an actor""" if actor.actor.entid == 0: sprite = self.sprite_provider.get_actor_placeholder( actor.actor.id, actor.pos.direction.id, self._redraw)[0] else: sprite = self.sprite_provider.get_monster( actor.actor.entid, actor.pos.direction.id, 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(self, subindex: int, widget: Gtk.DrawingArea, ctx: cairo.Context): scale = 2 portrait = self._portrait_provider.get( self.item_id, subindex, lambda: GLib.idle_add(widget.queue_draw), False) ctx.set_source_rgb(1, 1, 1) ctx.rectangle(0, 0, *widget.get_size_request()) ctx.fill() ctx.scale(scale, scale) ctx.set_source_surface(portrait) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() ctx.scale(1 / scale, 1 / scale) return True
def _do_draw(self, cr: cairo.Context) -> None: pixbuf = self.props.pixbuf if pixbuf is None: return scale = self._parent._widget_dist_from_canvas((1, 1)) offset = self._parent._widget_coord_from_canvas((0, 0)) with cairo_saved(cr): cr.translate(*offset) cr.scale(*scale) Gdk.cairo_set_source_pixbuf(cr, pixbuf, pixbuf_x=0, pixbuf_y=0) cr.get_source().set_filter(cairo.Filter.FAST) cr.paint()
def render_picture(ctx: cairo.Context, picture: Picture) -> None: """ Render a picture at (0, 0) onto the supplied context (which should use mm units). """ ctx.save() # Load the picture image_surface = cairo.ImageSurface.create_for_data( picture.get_image_bytes(), cairo.FORMAT_ARGB32, picture.image_width, picture.image_height, ) # Scale and translate the picture according to the scale/crop mode in use. # # NB: Pattern matrix maps from page space to pixel space, hence the # apparently inverted transformation described here. ctx.set_source_surface(image_surface) pattern = ctx.get_source() m = pattern.get_matrix() m.scale(1 / picture.scale, 1 / picture.scale) m.translate(-picture.x_offset, -picture.y_offset) pattern.set_matrix(m) # Draw the picture (clipped) ctx.rectangle(0, 0, picture.width, picture.height) ctx.fill() ctx.restore()
def this_source(ctx: Context, src): old = ctx.get_source() ctx.set_source(src) try: yield finally: ctx.set_source(old)
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 source(ctx: cairo.Context, source: cairo.Pattern): src = ctx.get_source() ctx.set_source(source) try: yield finally: ctx.set_source(src)
def draw(self, wdg, ctx: cairo.Context): ctx.set_antialias(cairo.Antialias.NONE) ctx.scale(self.scale, self.scale) # Background if self.map_bg is not None: if self.level_id == WORLD_MAP_DEFAULT_ID: # We display the bottom right of the map. ctx.set_source_surface(self.map_bg, -504, -1008) else: ctx.set_source_surface(self.map_bg, 0, 0) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() size_w, size_h = self.draw_area.get_size_request() size_w /= self.scale size_h /= self.scale # Tile Grid if self.draw_tile_grid: self.tile_grid_plugin.draw(ctx, size_w, size_h, self.mouse_x, self.mouse_y) # Selection self._handle_selection(ctx) # RENDER MARKERS self.markers_at_pos = {} for i, marker in enumerate(self.markers): if marker != self._editing and marker != self._hide and marker.level_id == self.level_id and marker.reference_id <= -1: self._draw_marker(ctx, marker) if self._editing: # Black out ctx.set_source_rgba(0, 0, 0, 0.5) ctx.rectangle(0, 0, size_w, size_h) ctx.fill() # Render editing marker self._draw_marker(ctx, self._editing) # nah, too crowded. #for (x, y), list_of_markers in self.markers_at_pos.items(): # ms = [self.markers.index(m) for m in list_of_markers] # self._draw_name(ctx, ms, x, y) return True
def screen(self, base_w, base_h, ctx: cairo.Context, display_id: int): if display_id == 0: self.decode_screen() ctx.translate(base_w * self._scale / 2, base_h * self._scale / 2) ctx.rotate(-radians(self._screen_rotation_degrees)) if self._screen_rotation_degrees == 90 or self._screen_rotation_degrees == 270: ctx.translate(-base_h * self._scale / 2, -base_w * self._scale / 2) else: ctx.translate(-base_w * self._scale / 2, -base_h * self._scale / 2) ctx.scale(self._scale, self._scale) if display_id == 0: ctx.set_source_surface(self._upper_image) else: ctx.set_source_surface(self._lower_image) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() if self._after_render_hook: self._after_render_hook(ctx, display_id)
def draw_full(self, ctx: cairo.Context, bma_chunks: List[int], bma_chunk_width: int, bma_chunk_height: int): if bma_chunk_width != self._cached__bma_chunk_width or self._cached__bma_chunks != bma_chunks: self._cached__bma_chunk_width = bma_chunk_width self._cached__bma_chunks = list(bma_chunks) self._cached = None if self._cached is None: drawer = DmaDrawer(self.dma) if self.fixed_room: rules = drawer.rules_from_fixed_room(self.fixed_room) else: rules = drawer.rules_from_bma(bma_chunks, bma_chunk_width) mappings = drawer.get_mappings_for_rules( rules, treat_outside_as_wall=True, variation_index=0) frame = pil_to_cairo_surface( drawer.draw(mappings, self.dpci, self.dpc, self.dpl, None)[0].convert('RGBA')) self._cached = frame ctx.set_source_surface(self._cached) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint()
y0 = H//2 + (random.uniform()-.1)*50 for dx,dy in spiral(): c = .25+.75*random.random() x = int(x0+dx) y = int(y0+dy) checked = False I.flush() if not (x <= w//2 or y <= h//2 or x >= (W-w//2) or y >= (H-h//2)): ndI = ndarray(shape=(h,w), buffer=I.get_data(), dtype=ubyte, order='C', offset=(x-w//2) + I.get_stride() * (y-h//2), strides=[I.get_stride(), 1]) ndL = ndarray(shape=(h,w), buffer=L.get_data(), dtype=ubyte, order='C', strides=[L.get_stride(), 1]) if ((ndI * ndL).sum() == 0): checked = True new_region = RectangleInt(x-w//2, y-h//2, w, h) if (checked or ( drawn_regions.contains_rectangle(new_region) == REGION_OVERLAP_OUT )): ctxI.set_source_surface(L, 0, 0) pattern = ctxI.get_source() scalematrix = Matrix() scalematrix.scale(1.0,1.0) scalematrix.translate(w//2 - x, h//2 - y) pattern.set_matrix(scalematrix) ctxI.set_source_rgba(c,c,c,c) ctxI.mask(pattern) drawn_regions.union(new_region) break I.flush() I.write_to_png("wordle-cairo.png") Image.open("wordle-cairo.png").show()
def draw_action(self, ctx: cairo.Context, action: FixedFloorActionRule, sx: int, sy: int): if isinstance(action, EntityRule): assert self.parent.entity_rule_container is not None item, monster, tile, stats = self.parent.entity_rule_container.get( action.entity_rule_id) # Has trap? if tile.trap_id < 25: self._draw_trap(ctx, tile.trap_id, sx, sy) # Has item? if item.item_id > 0: try: self._draw_item(ctx, item.item_id, sx, sy) except IndexError: ctx.arc(sx + DPCI_TILE_DIM * DPC_TILING_DIM / 2, sy + DPCI_TILE_DIM * DPC_TILING_DIM / 2, DPCI_TILE_DIM * DPC_TILING_DIM / 2, 0, 2 * math.pi) ctx.set_source_rgba(*COLOR_ITEM) ctx.fill_preserve() ctx.set_source_rgba(*COLOR_OUTLINE) ctx.set_line_width(1) ctx.stroke() # Has Pokémon? if monster.md_idx > 0: self._draw_pokemon(ctx, monster.md_idx, action.direction, sx, sy) elif isinstance(action, TileRule): # Leader spawn tile if action.tr_type == TileRuleType.LEADER_SPAWN: self.parent.draw_placeholder(0, sx, sy, action.direction, ctx) # Attendant1 spawn tile if action.tr_type == TileRuleType.ATTENDANT1_SPAWN: self.parent.draw_placeholder(10, sx, sy, action.direction, ctx) # Attendant2 spawn tile if action.tr_type == TileRuleType.ATTENDANT2_SPAWN: self.parent.draw_placeholder(11, sx, sy, action.direction, ctx) # Attendant3 spawn tile if action.tr_type == TileRuleType.ATTENDANT3_SPAWN: self.parent.draw_placeholder(15, sx, sy, action.direction, ctx) # Key walls if action.tr_type == TileRuleType.FL_WA_ROOM_FLAG_0C or action.tr_type == TileRuleType.FL_WA_ROOM_FLAG_0D: sprite, x, y, w, h = self.parent.sprite_provider.get_for_trap( 31, lambda: GLib.idle_add(self.parent.redraw)) ctx.translate(sx, sy) ctx.set_source_surface(sprite) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() ctx.translate(-sx, -sy) # Warp zone if action.tr_type == TileRuleType.WARP_ZONE or action.tr_type == TileRuleType.WARP_ZONE_2: self._draw_stairs(ctx, sx, sy) elif isinstance(action, DirectRule): if action.tile.room_type == RoomType.KECLEON_SHOP: sprite, x, y, w, h = self.parent.sprite_provider.get_for_trap( 30, lambda: GLib.idle_add(self.parent.redraw)) ctx.translate(sx, sy) ctx.set_source_surface(sprite) ctx.get_source().set_filter(cairo.Filter.NEAREST) ctx.paint() ctx.translate(-sx, -sy) if action.tile.typ == TileType.PLAYER_SPAWN or action.tile.typ == TileType.ENEMY: self._draw_pokemon(ctx, action.itmtpmon_id, action.direction, sx, sy) if action.tile.typ == TileType.STAIRS: self._draw_stairs(ctx, sx, sy) if action.tile.typ == TileType.TRAP: self._draw_trap(ctx, action.itmtpmon_id, sx, sy) if action.tile.typ == TileType.BURIED_ITEM: self._draw_item(ctx, action.itmtpmon_id, sx, sy, buried=True) if action.tile.typ == TileType.ITEM: self._draw_item(ctx, action.itmtpmon_id, sx, sy) if action.tile.room_type == RoomType.MONSTER_HOUSE: ctx.set_source_rgba(230, 0, 0, 0.2) ctx.rectangle(sx, sy, DPCI_TILE_DIM * DPC_TILING_DIM, DPCI_TILE_DIM * DPC_TILING_DIM) ctx.fill()
# Draw surface = ImageSurface(FORMAT_ARGB32, 1200, 500) ctx = Context(surface) # fill background as gray ctx.rectangle(0,0,1200,500) ctx.set_source_rgb (0.5 , 0.5, 0.5) ctx.fill() # use the stroked font's size as scale, as it is likely slightly larger scale = 400.0 / rowsZ # draw bitmap first ctx.set_source_surface(F, 0, 0) patternF = ctx.get_source() SurfacePattern.set_filter(patternF, FILTER_BEST) scalematrix = Matrix() scalematrix.scale(1.0/scale,1.0/scale) scalematrix.translate(-(600.0 - widthF *scale /2.0 ), -50) patternF.set_matrix(scalematrix) ctx.set_source_rgb (1 , 1, 0) ctx.mask(patternF) ctx.fill() scalematrix.translate(+400,0) patternF.set_matrix(scalematrix) ctx.mask(patternF) ctx.fill()
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 face.load_char('S', FT_LOAD_RENDER | FT_LOAD_TARGET_LCD_V ) bitmap = face.glyph.bitmap