def _do_draw(self, cr: cairo.Context) -> None: mask = self._mask if mask 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) mask_width = mask.shape[1] mask_height = mask.shape[0] required_stride_len = cairo.Format.A8.stride_for_width(mask_width) required_padding = required_stride_len - mask_width if required_padding: mask = np.pad(mask, pad_width=((0, 0), (0, required_padding)), mode='constant', constant_values=0) mask_surface = cairo.ImageSurface.create_for_data( memoryview(mask), cairo.FORMAT_A8, mask_width, mask_height, ) cr.set_source_rgba(*self._color) cr.mask_surface(mask_surface, 0, 0)
def draw(self, cr: cairo.Context, drawing_options: DrawingOptions): cr.set_source_rgb(*drawing_options.sleeper_color) cr.set_line_width(2) # Main sleepers cr.save() cr.move_to(0, 0) cr.line_to(25, 4 * self.coordinate_sign) cr.line_to(32, 4 * self.coordinate_sign) cr.line_to(32, -4 * self.coordinate_sign) cr.line_to(0, -4 * self.coordinate_sign) cr.close_path() cr.clip() for i in range(0, 36, 4): cr.move_to(i, -4) cr.line_to(i, 4) cr.stroke() cr.restore() # Branch sleepers cr.save() cr.move_to(0, 0) cr.line_to(25, 4 * self.coordinate_sign) cr.line_to(32, 4 * self.coordinate_sign) cr.line_to(40, 4 * self.coordinate_sign) cr.line_to(40, 32 * self.coordinate_sign) cr.line_to(0, 32 * self.coordinate_sign) cr.close_path() cr.clip() # cr.stroke() for i in range(0, 10): x, y, theta = self.point_position("in", i / 9 * self.branch_length, out_anchor="branch") theta += -math.pi / 2 x_off, y_off = math.cos(theta) * 4, math.sin(theta) * 4 cr.move_to(x + x_off, y + y_off) cr.line_to(x - x_off, y - y_off) cr.stroke() cr.restore() if self.state == "out": rail_draw_order = ("branch", "out") else: rail_draw_order = ("out", "branch") cr.save() mask = cairo.ImageSurface( cairo.FORMAT_ARGB32, math.ceil(40 * drawing_options.scale), math.ceil(80 * drawing_options.scale), ) mask_cr = cairo.Context(mask) mask_cr.scale(drawing_options.scale, drawing_options.scale) mask_cr.translate(0, 40) mask_cr.set_source_rgb(0, 1, 0) for anchor_name in rail_draw_order: self.draw_rails_path(mask_cr, anchor_name) mask_cr.set_operator(cairo.OPERATOR_CLEAR) mask_cr.set_line_width(8) mask_cr.stroke_preserve() mask_cr.set_operator(cairo.OPERATOR_SOURCE) mask_cr.set_line_width(6) mask_cr.stroke_preserve() mask_cr.set_operator(cairo.OPERATOR_CLEAR) mask_cr.set_line_width(4) mask_cr.stroke() cr.set_source_rgb(*drawing_options.rail_color) cr.scale(1 / drawing_options.scale, 1 / drawing_options.scale) cr.mask_surface(mask, 0, -40 * drawing_options.scale) cr.restore()