Example #1
0
    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)
Example #2
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()