Exemple #1
0
    def draw_base(self, cr: cairo.Context):
        cr.identity_matrix()
        cr.set_matrix(self.matrix)

        cr.rectangle(-1, -1, 2, 2)
        cr.set_source_rgb(*colors[0])
        cr.fill()

        if self.gtk_mode:
            cr.rectangle(-1, .65, .15, .35)
            cr.set_source_rgb(*colors[1])
            cr.fill()

        cr.set_source_rgb(*colors[1])
        cr.set_line_width(9e-3)

        cr.arc(0, 0, self.radius, 0, 2 * PI)
        # cr.stroke()
        for theta in np.linspace(0, 2 * PI, self.radio_button + 1):
            cr.move_to(0, 0)
            x, y = self.radius * np.cos(theta), self.radius * np.sin(theta)
            cr.line_to(x, y)
            if (x, y) not in self.inter_sections:
                self.inter_sections.append((x, y))
        cr.stroke()
Exemple #2
0
    def fill(
        self,
        ctx: cairo.Context,
        rng: Generator,
        x1: float,
        y1: float,
        x2: float,
        y2: float,
    ):
        with source(ctx, self.stops[-1].to_pattern()):
            ctx.fill_preserve()

        # Orient the canvas so that our gradient goes straight in direction of +Y.
        gradient_angle = angle((x1, y1), (x2, y2)) - (pi / 2)
        with translation(ctx, x1, y1), rotation(ctx, gradient_angle), source(
                ctx, self.stops[0].to_pattern()):
            # We translated and rotated the canvas, so our gradient control
            # vector is now from (0, 0) straight up:
            grad_control_y = distance((x1, y1), (x2, y2))
            # Get a bounding box of what needs to be filled:
            start_x, start_y, end_x, end_y = ctx.fill_extents()
            ctx.new_path()

            for cx, cy, cr in self.pattern.func(
                    rng,
                (start_x, start_y),
                (end_x, end_y),
                (0, 0),
                (0, grad_control_y),
                    self.dot_radius,
            ):
                ctx.arc(cx, cy, cr, 0, tau)
                ctx.fill()
Exemple #3
0
def ellipse(ctx: cairo.Context,
            cell_structure: mat.CellStructure,
            r: float = 2) -> None:
    """
    Draw an ellipse in the given context.

    Drawing is centered relative to cell structure, and semi-major is aligned 
    with vertical coordinate axis.

    :param ctx: Current context.
    :param cell_structure: Assumptions about structure of the cell being drawn.
    :param r: Semi-major over semi-minor, must be > 2.
    """

    if not 2 <= r:
        raise ValueError()

    width, height = _get_dims(cell_structure)

    ctx.save()
    ctx.translate(cell_structure.width / 2., cell_structure.height / 2.)
    ctx.scale(width / (2 * r), height / 2)
    ctx.new_sub_path()
    ctx.arc(0., 0., 1., 0., 2 * math.pi)
    ctx.restore()
Exemple #4
0
    def draw(self, cr: cairo.Context) -> None:
        xc = self._xc
        yc = self._yc
        radius = self._radius
        scale_radius = self._scale_radius
        fill_color = self._fill_color

        if radius == 0.0:
            return

        matrix = cr.get_matrix()
        dx = 1 / matrix.xx
        dy = 1 / matrix.yy

        if scale_radius:
            radius_scale = 1 / (0.5 * (matrix.xx + matrix.yy))
        else:
            radius_scale = 1.0

        cr.arc(xc, yc, radius_scale * radius, 0, 2 * math.pi)
        cr.set_source_rgba(*fill_color)
        cr.fill()

        self._last_drawn_region = circle_region(
            xc, yc, radius_scale * radius + max(dx, dy))
        self._last_drawn_radius_scale = radius_scale
    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 draw_highlight_layer(self, layout: Layout, cr: Context):
     if isinstance(self.highlight_item, Piece):
         self.draw_piece(self.highlight_item, cr, self.highlight_drawing_options)
     if isinstance(self.selected_item, Piece):
         self.draw_piece(self.selected_item, cr, self.selection_drawing_options)
     elif isinstance(self.selected_item, Anchor) and self.selected_item.position:
         cr.arc(
             self.selected_item.position.x,
             self.selected_item.position.y,
             3
             if any(
                 piece.placement and anchor_name == piece.anchor_names[0]
                 for piece, anchor_name in self.selected_item.items()
             )
             else 1,
             0,
             math.tau,
         )
         cr.set_source_rgb(0.2, 0.2, 1)
         cr.fill()
     elif (
         isinstance(self.selected_item, TracksideItem)
         and self.selected_item.position
     ):
         self.draw_sensor(
             self.selected_item, layout, cr, self.selection_drawing_options
         )
Exemple #7
0
def draw_player(cr: cairo.Context, player: Player) -> None:
    with save_context(cr):
        cr.translate(player.x, player.y)

        with save_context(cr):
            cr.rotate(player.rotation)

            # draw player
            cr.set_source_rgb(0, 0, 0)
            cr.arc(0, 0, 10, 0, math.tau)
            cr.fill()

            # draw arms
            cr.move_to(2, -10)
            cr.rel_line_to(12, 0)
            cr.move_to(2, 10)
            cr.rel_line_to(12, 0)
            cr.stroke()

        # draw health
        cr.set_source_rgb(1, 1, 1)
        cr.rectangle(-20, -35, 40, 8)
        cr.fill()
        # cr.set_source_rgb(.1, .9, .2)
        cr.set_source_rgb(2 * (1 - player.health), 2 * player.health, 0)
        cr.rectangle(-20, -35, 40 * player.health, 8)
        cr.fill()
        cr.set_line_width(1)
        cr.set_source_rgb(0, 0, 0)
        cr.rectangle(-20, -35, 40, 8)
        cr.stroke()
Exemple #8
0
def draw_dot(context: cairo.Context, dot: symbols.Dot) -> None:
    """draw a filled circle"""
    context.set_line_width(dot.thickness)
    _set_color(context, dot.color)

    context.arc(dot.center[0], dot.center[1], dot.radius, 0.0, 2.0 * np.pi)
    context.stroke_preserve()
    context.fill()
    def draw_trains(self, layout: Layout, cr: Context):
        for train in layout.trains.values():
            car_start = train.position

            annotation = train.meta.get("annotation")

            for i, car in enumerate(train.cars):
                front_bogey_offset, rear_bogey_offset = car.bogey_offsets
                bogey_spacing = rear_bogey_offset - front_bogey_offset
                front_bogey_position = car_start - front_bogey_offset
                front_bogey_xy = self.transform_track_point(front_bogey_position)
                rear_bogey_position, rear_bogey_xy = self.point_back(
                    front_bogey_position, bogey_spacing
                )

                cr.save()
                cr.translate(front_bogey_xy[0], front_bogey_xy[1])
                cr.rotate(
                    math.pi
                    + math.atan2(
                        front_bogey_xy[1] - rear_bogey_xy[1],
                        front_bogey_xy[0] - rear_bogey_xy[0],
                    )
                )

                cr.set_source_rgb(*hex_to_rgb(train.meta.get("color", "#a0a0ff")))

                if i == 0 and annotation:
                    cr.move_to(0, -10)
                    cr.set_font_size(5)
                    cr.show_text(annotation)

                cr.set_line_width(4)
                cr.move_to(-front_bogey_offset, 0)
                cr.line_to(car.length - front_bogey_offset, 0)
                cr.stroke()

                cr.set_line_width(6)
                cr.move_to(1 - front_bogey_offset, 0)
                cr.line_to(car.length - front_bogey_offset - 1, 0)
                cr.stroke()

                if i == 0 and train.lights_on:
                    cr.set_source_rgba(1, 1, 0.2, 0.5)
                    for y in (-2.5, 2.5):
                        cr.move_to(-front_bogey_offset - 1, y)
                        cr.arc(
                            -front_bogey_offset - 1,
                            y,
                            10,
                            6 / 7 * math.pi,
                            math.pi * 8 / 7,
                        )
                        cr.close_path()
                        cr.fill()

                cr.restore()
                car_start = rear_bogey_position - (car.length - rear_bogey_offset + 1)
Exemple #10
0
def draw_router_transmission(args, ld: Path, area, r, ctx: cairo.Context):
    ctx.rectangle(0, 0, area.x, area.y)
    ctx.set_source_rgba(*color_db(args))
    ctx.fill()

    # transmitting circles
    for router in r:
        if not router.mm.visible:
            continue
        x, y = router.coordinates()

        if router.transmission_within_second:
            distance = \
                max(router.interfaces.values(), key=lambda x: x['range'])[
                    'range']
            ctx.set_source_rgba(*color_transmission_circle(args))
            ctx.move_to(x, y)
            ctx.arc(x, y, distance, 0, 2 * math.pi)
            ctx.fill()

    for router in r:
        if not router.mm.visible:
            continue
        x, y = router.coordinates()

        ctx.set_line_width(0.1)
        path_thickness = 6.0
        # iterate over links
        for i, interface_name in enumerate(router.interfaces):
            range_ = router.interfaces[interface_name]['range']

            # draw lines between links
            ctx.set_line_width(path_thickness)
            for r_id, r_obj in router.connections[interface_name].items():
                if not r_obj.mm.visible:
                    continue
                other_x, other_y = r_obj.coordinates()
                ctx.move_to(x, y)
                ctx.set_source_rgba(*color_tx_links(args))
                ctx.line_to(other_x, other_y)
                ctx.stroke()

            path_thickness -= 4.0
            if path_thickness < 2.0:
                path_thickness = 2.0

    # draw dots over all
    for router in r:
        if not router.mm.visible:
            continue
        x, y = router.coordinates()

        ctx.set_line_width(0.0)
        ctx.set_source_rgba(*color_tx_links(args))
        ctx.move_to(x, y)
        ctx.arc(x, y, 5, 0, 2 * math.pi)
        ctx.fill()
def create_image(context: cairo.Context, cells: CellBlock,
                 cell_sizes: Dict[CellBlock, float]) -> None:
    context.rectangle(0, 0, WIDTH, HEIGHT)
    context.set_source_rgb(1, 1, 1)
    context.fill()

    context.set_source_rgb(0, 0, 0)
    for (x, y), cell_state in cells.items():
        context.arc(x * 16, y * 16, cell_sizes[cell_state], 0, 2 * pi)
        context.fill()
Exemple #12
0
    def draw(self, cr: Context, drawing_options: DrawingOptions):

        cr.set_source_rgb(*drawing_options.rail_color)
        cr.rectangle(-1, -1, 2, 2)
        cr.fill()

        cr.set_source_rgb(
            *(SENSOR_ACTIVATED if self.activated else SENSOR_NORMAL))
        cr.arc(0, 0, 0.8, 0, math.tau)
        cr.fill()
Exemple #13
0
class Canvas:

    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 fit(self, left, top, right, bottom):
        xoff = left
        yoff = top
        
        xscale = self.width / float(right - left)
        yscale = self.height / float(bottom - top)
        
        if abs(xscale) > abs(yscale):
            xscale *= abs(yscale) / abs(xscale)
        
        elif abs(xscale) < abs(yscale):
            yscale *= abs(xscale) / abs(yscale)

        self.xform = lambda x, y: ((x - xoff) * xscale, (y - yoff) * yscale)
    
    def dot(self, x, y, size=4, fill=(.5, .5, .5)):
        x, y = self.xform(x, y)

        self.ctx.arc(x, y, size/2., 0, 2*pi)
        self.ctx.set_source_rgb(*fill)
        self.ctx.fill()
    
    def line(self, points, stroke=(.5, .5, .5), width=1):
        self.ctx.move_to(*self.xform(*points[0]))
        
        for (x, y) in points[1:]:
            self.ctx.line_to(*self.xform(x, y))
        
        self.ctx.set_source_rgb(*stroke)
        self.ctx.set_line_cap(LINE_CAP_ROUND)
        self.ctx.set_line_width(width)
        self.ctx.stroke()
    
    def save(self, filename):
        self.img.write_to_png(filename)
Exemple #14
0
class Canvas:
    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 fit(self, left, top, right, bottom):
        xoff = left
        yoff = top

        xscale = self.width / float(right - left)
        yscale = self.height / float(bottom - top)

        if abs(xscale) > abs(yscale):
            xscale *= abs(yscale) / abs(xscale)

        elif abs(xscale) < abs(yscale):
            yscale *= abs(xscale) / abs(yscale)

        self.xform = lambda x, y: ((x - xoff) * xscale, (y - yoff) * yscale)

    def dot(self, x, y, size=4, fill=(.5, .5, .5)):
        x, y = self.xform(x, y)

        self.ctx.arc(x, y, size / 2., 0, 2 * pi)
        self.ctx.set_source_rgb(*fill)
        self.ctx.fill()

    def line(self, points, stroke=(.5, .5, .5), width=1):
        self.ctx.move_to(*self.xform(*points[0]))

        for (x, y) in points[1:]:
            self.ctx.line_to(*self.xform(x, y))

        self.ctx.set_source_rgb(*stroke)
        self.ctx.set_line_cap(LINE_CAP_ROUND)
        self.ctx.set_line_width(width)
        self.ctx.stroke()

    def save(self, filename):
        self.img.write_to_png(filename)
Exemple #15
0
def draw_crown(ctx: cairo.Context, pos_x: float, pos_y: float, radius: float):
    ctx.arc(pos_x, pos_y, radius, 0, tau)
    ctx.stroke_preserve()
    ctx.clip()

    crown_eclipse = -0.2

    eclipse_cy = pos_y + crown_eclipse * 2.0 * radius
    ctx.arc(pos_x, eclipse_cy, radius, 0, tau)
    ctx.fill()
    ctx.reset_clip()
    def draw_piece(self, piece: Piece, cr: Context, drawing_options: DrawingOptions):
        if not piece.position:
            return

        cr.save()

        cr.translate(piece.position.x, piece.position.y)
        cr.rotate(piece.position.angle)

        piece.draw(cr, drawing_options)

        relative_positions = piece.relative_positions()

        for anchor_name, anchor in piece.anchors.items():
            # if anchor.position != piece.position + relative_positions[anchor_name] + Position(0, 0, math.pi):
            #     cr.move_to(0, 0)
            #     cr.line_to(anchor.position.x, anchor.position.y)
            #     cr.stroke()

            cr.save()

            cr.translate(
                relative_positions[anchor_name].x, relative_positions[anchor_name].y
            )
            cr.rotate(relative_positions[anchor_name].angle)

            if len(anchor) == 2:
                cr.set_source_rgb(1, 0.5, 0.5)
            else:
                cr.set_source_rgb(0.5, 1, 0.5)

            next_piece, next_anchor_name = anchor.next(piece)

            cr.arc(
                0,
                0,
                3
                if (piece.placement and anchor_name == piece.anchor_names[0])
                or (
                    next_piece
                    and next_piece.placement
                    and next_anchor_name == next_piece.anchor_names[0]
                )
                else 1,
                0,
                math.tau,
            )
            cr.fill()

            cr.restore()
        cr.restore()
    def draw(self, ctx: cairo.Context):
        with translation(ctx, self.pos[0], self.pos[1]):
            with rotation(ctx, self.rotation):
                with source(ctx, self.color.to_pattern()):
                    ctx.arc(0, 0, self.size, 0, math.tau)
                    ctx.fill()

                if self.iris:
                    self.iris.draw(ctx, relative_to=self.pos)

                self.pupil.draw(ctx, relative_to=self.pos)

                if self.eyelids:
                    self.eyelids.draw(ctx, self.size, relative_to=self.pos)
Exemple #18
0
    def draw(self, cr: cairo.Context) -> None:
        line = self._line
        if line is None:
            return

        viewport_extents = self._parent.props.viewport_extents

        p0 = line.p0
        p1 = line.p1

        if p0 == p1:
            return

        start_point = line.eval_at(x=viewport_extents.x0)
        end_point = line.eval_at(x=viewport_extents.x1)

        if not viewport_extents.contains_point(start_point):
            if start_point.y < viewport_extents.y0:
                y_to_eval = viewport_extents.y0
            else:
                y_to_eval = viewport_extents.y1
            start_point = line.eval_at(y=y_to_eval)

        if not viewport_extents.contains_point(end_point):
            if end_point.y < viewport_extents.y0:
                y_to_eval = viewport_extents.y0
            else:
                y_to_eval = viewport_extents.y1
            end_point = line.eval_at(y=y_to_eval)

        p0, p1, start_point, end_point = map(self._parent._widget_coord_from_canvas, (p0, p1, start_point, end_point))

        cr.move_to(*start_point)
        cr.line_to(*end_point)

        stroke_width = self.props.stroke_width
        stroke_color = self.props.stroke_color

        cr.set_line_width(stroke_width)
        cr.set_source_rgb(*stroke_color)  # red, green, blue
        cr.stroke()

        # Draw the control points of the line.
        if self.props.draw_control_points:
            cr.arc(*p0, stroke_width*2, 0, 2*math.pi)
            cr.close_path()
            cr.arc(*p1, stroke_width*2, 0, 2*math.pi)
            cr.close_path()
            cr.fill()
Exemple #19
0
def draw_circle(context: cairo.Context, circle: symbols.Circle) -> None:
    """draw a circle"""
    context.set_line_width(circle.thickness)
    _set_color(context, circle.color)

    # TODO: it's still a bit unclear whether I should use arc or arc_negative
    # to match opencv behavior
    if circle.start_angle > circle.end_angle:
        context.arc_negative(circle.center[0], circle.center[1], circle.radius,
                             circle.start_angle, circle.end_angle)
    else:
        context.arc(circle.center[0], circle.center[1], circle.radius,
                    circle.start_angle, circle.end_angle)

    context.stroke()
Exemple #20
0
    def paint_foreground(self, ctx: Context):
        ctx.set_source_rgba(*Color.GRAY40)
        rect = Rectangle(ZERO_TOP_LEFT, self.size)
        center = rect.position(Anchor.CENTER_CENTER)
        r = min(*self.size) / 2
        ctx.move_to(center.x, center.y)
        φ = 2 * math.pi * datetime.now().microsecond / 1000000
        ctx.arc(*center, r, -math.pi / 2, φ - math.pi / 2)
        ctx.line_to(center.x, center.y)
        ctx.fill()

        ctx.move_to(center.x, center.y)
        ctx.line_to(center.x + r * math.sin(φ), center.y - r * math.cos(φ))
        ctx.set_line_width(2)
        ctx.set_source_rgba(*Color.WHITE)
        ctx.stroke()
Exemple #21
0
def rounded_rect(ctx: Context, x, y, width, height, radius):
    def deg(value):
        return value * math.pi / 180.0

    ctx.new_sub_path()
    ctx.arc(x + width - radius, y + radius, radius, deg(-90), deg(0))
    ctx.arc(x + width - radius, y + height - radius, radius, deg(0), deg(90))
    ctx.arc(x + radius, y + height - radius, radius, deg(90), deg(180))
    ctx.arc(x + radius, y + radius, radius, deg(180), deg(270))
    ctx.close_path()
Exemple #22
0
    def do_draw(self, ctx: Context):
        allocation = self.get_allocation()
        width = allocation.width / 2 if allocation.width < allocation.height else allocation.height / 2

        ctx.set_line_width(width / 10)
        ctx.set_line_cap(LINE_CAP_ROUND)

        point = self.size * (self.progress / 100) + self.start
        end = self.size + self.start

        ctx.arc(allocation.width / 2, allocation.height / 2, width * 0.9,
                point, end)
        set_rgb(ctx, self.track_color)
        ctx.stroke()

        ctx.arc(allocation.width / 2, allocation.height / 2, width * 0.9,
                self.start, point)
        set_rgb(ctx, self.color)
        ctx.stroke()
Exemple #23
0
def _calendar_base(
    ctx: cairo.Context,
    pos_x: float,
    pos_y: float,
    radius_outer: float,
    radius_inner: float,
    chunks: int,
):
    ctx.arc(pos_x, pos_y, radius_outer, 0, tau)
    ctx.stroke_preserve()

    ctx.arc(pos_x, pos_y, radius_inner, 0, tau)
    ctx.stroke()

    for (start_x, start_y), (end_x, end_y) in zip(
            points_along_arc(pos_x, pos_y, radius_inner, 0, tau, chunks),
            points_along_arc(pos_x, pos_y, radius_outer, 0, tau, chunks),
    ):
        ctx.move_to(start_x, start_y)
        ctx.line_to(end_x, end_y)
        ctx.stroke()
    def draw(self, ctx: cairo.Context, relative_to=(0, 0)):
        pos = self.pos - relative_to

        top_intersection = pos + np.array([0, self.size])
        bottom_intersection = pos - np.array([0, self.size])
        right_edge = pos + np.array([self.width / 2, 0])
        left_edge = pos - np.array([self.width / 2, 0])

        center_1, rad_1 = circle_from_3_points(top_intersection, right_edge,
                                               bottom_intersection)
        center_2, rad_2 = circle_from_3_points(top_intersection, left_edge,
                                               bottom_intersection)

        ctx.arc(center_1[0], center_1[1], rad_1, 0, math.tau)
        ctx.clip()

        ctx.arc(center_2[0], center_2[1], rad_2, 0, math.tau)
        ctx.clip()

        ctx.paint()
        ctx.reset_clip()
def draw_moon_cycles(
    ctx: cairo.Context,
    rng: Generator,
    pos_x: float,
    pos_y: float,
    radius_outer: float,
    radius_inner: float,
):
    ctx.arc(pos_x, pos_y, radius_outer, 0, tau)
    ctx.arc(pos_x, pos_y, radius_inner, 0, tau)
    ctx.stroke()

    n_moons = rng.integers(6, 12)

    for i, (x, y) in enumerate(
        points_along_arc(
            pos_x, pos_y, (radius_outer + radius_inner) / 2.0, 0, tau, n_moons
        )
    ):
        pct_done = i / n_moons
        eclipse_pct = (pct_done * 2.0) - 1.0
        draw_moon(ctx, x, y, (radius_outer - radius_inner) / 2.3, eclipse_pct)
Exemple #26
0
def draw_star_band(
    ctx: cairo.Context,
    rng: Generator,
    pos_x: float,
    pos_y: float,
    radius_outer: float,
    radius_inner: float,
):
    band_center = (radius_outer + radius_inner) / 2
    star_size = 0.2 * (radius_outer - radius_inner)
    n_stars = rng.integers(20, 50)

    ctx.arc(pos_x, pos_y, radius_outer, 0, tau)
    ctx.arc_negative(pos_x, pos_y, radius_inner, 0, -tau)
    ctx.stroke_preserve()
    ctx.clip_preserve()

    grad_offset_x = rng.uniform(radius_inner / 3.0, radius_inner)
    grad_offset_y = rng.uniform(radius_inner / 3.0, radius_inner)
    grad = PointLinearGradient(
        [Color(0, 0, 0), Color(1, 1, 1, 0.0)], Pattern.PACKED)
    grad.fill(
        ctx,
        rng,
        pos_x - grad_offset_x,
        pos_y - grad_offset_y,
        pos_x + grad_offset_x,
        pos_y + grad_offset_y,
    )

    for x, y in jitter_points(
            points_along_arc(pos_x, pos_y, band_center, 0, tau, n_stars), rng,
            star_size):
        draw_star(ctx, rng, x, y, star_size)

    ctx.reset_clip()
def draw_moon(
    ctx: cairo.Context,
    pos_x: float,
    pos_y: float,
    radius: float,
    eclipse_pct: float = -1.0,
):
    moon_color = Color(0.9, 0.9, 0.9)

    ctx.arc(pos_x, pos_y, radius, 0, tau)
    ctx.stroke_preserve()

    with source(
        ctx,
        moon_color.to_pattern(),
    ):
        ctx.fill_preserve()
        ctx.clip()

    with source(ctx, Color(0.0, 0.0, 0.0).to_pattern()):
        eclipse_cx = pos_x + eclipse_pct * 2.0 * radius
        ctx.arc(eclipse_cx, pos_y, radius, 0, tau)
        ctx.fill()
        ctx.reset_clip()
    def draw(self, ctx: cairo.Context, eye_radius: float, relative_to=(0, 0)):
        pos = self.pos - relative_to

        top_intersection = pos + np.array([0, self.opening / 2])
        bottom_intersection = pos - np.array([0, self.opening / 2])
        right_point = pos + np.array([self.size, 0])
        left_point = pos - np.array([self.size, 0])

        center_1, rad_1 = circle_from_3_points(left_point, top_intersection,
                                               right_point)
        center_2, rad_2 = circle_from_3_points(left_point, bottom_intersection,
                                               right_point)

        # Eyelid 1:
        ctx.push_group()
        with source(ctx, self.color.to_pattern()):
            # Restrict drawing area to eyeball:
            ctx.arc(pos[0], pos[1], eye_radius + 1, 0, math.tau)
            ctx.clip()
            ctx.paint()
            # Sub circle 1:
            with operator(ctx, cairo.Operator.CLEAR):
                ctx.arc(center_1[0], center_1[1], rad_1, 0, math.tau)
                ctx.fill()
            ctx.reset_clip()
        with source(ctx, ctx.pop_group()):
            ctx.paint()

        # Eyelid 2:
        ctx.push_group()
        with source(ctx, self.color.to_pattern()):
            # Restrict drawing area to eyeball:
            ctx.arc(pos[0], pos[1], eye_radius + 1, 0, math.tau)
            ctx.clip()
            ctx.paint()
            # Sub circle 2:
            with operator(ctx, cairo.Operator.CLEAR):
                ctx.arc(center_2[0], center_2[1], rad_2, 0, math.tau)
                ctx.fill()
            ctx.reset_clip()
        with source(ctx, ctx.pop_group()):
            ctx.paint()
Exemple #29
0
    def draw(self, cr: cairo.Context, drawing_options: DrawingOptions):
        if self.direction == CurveDirection.left:
            cy = -self.radius
            angle1, angle2 = math.pi / 2 - math.tau / self.per_circle, math.pi / 2
        else:
            cy = self.radius
            angle1, angle2 = -math.pi / 2, math.tau / self.per_circle - math.pi / 2

        cr.save()

        cr.set_source_rgb(0.9, 0.9, 0.9)
        cr.move_to(0, cy)
        cr.arc(0, cy, self.radius + 5, angle1, angle2)
        cr.line_to(0, cy)
        cr.clip()

        for i in range(0, self.sleepers + 1):
            angle = (math.tau / self.per_circle) * (i / self.sleepers)
            if self.direction == CurveDirection.left:
                angle = -math.pi / 2 - angle
            else:
                angle = angle + math.pi / 2
            cr.move_to(
                -math.cos(angle) * (self.radius - 4),
                cy - math.sin(angle) * (self.radius - 4),
            )
            cr.line_to(
                -math.cos(angle) * (self.radius + 4),
                cy - math.sin(angle) * (self.radius + 4),
            )

        cr.set_line_width(2)
        cr.set_source_rgb(*drawing_options.sleeper_color)
        cr.stroke()

        cr.set_line_width(1)
        cr.set_source_rgb(*drawing_options.rail_color)
        cr.arc(0, cy, self.radius - 2.5, angle1, angle2)
        cr.stroke()
        cr.arc(0, cy, self.radius + 2.5, angle1, angle2)
        cr.stroke()

        cr.restore()
Exemple #30
0
 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()
        start = end+1
    ctx.fill_preserve()
    ctx.set_source_rgb(0,1,0)
    ctx.stroke()

    start, end = 0, 0
    for i in range(len(outline.contours)):
        end    = outline.contours[i]

        ctx.new_path()
        ctx.set_source_rgb(0,0,1)
        for j in range(start, end+1):
            if ( Curve_Tag[j] == FT_Curve_Tag_On ):
                point = outline.points[j]
                ctx.move_to(point[0],point[1])
                ctx.arc(point[0], point[1], 40, 0, 2 * math.pi)
        ctx.fill()

        ctx.new_path()
        ctx.set_source_rgb(1,0,0)
        for j in range(start, end+1):
            if ( Curve_Tag[j] != FT_Curve_Tag_On ):
                point = outline.points[j]
                ctx.move_to(point[0],point[1])
                ctx.arc(point[0], point[1], 10, 0, 2 * math.pi)
        ctx.fill()

        points = outline.points[start:end+1]
        points.append(points[0])
        tags   = outline.tags[start:end+1]
        tags.append(tags[0])