Example #1
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()
Example #2
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()
Example #3
0
    def draw(self, cr: cairo.Context) -> None:
        start_angle = self._start_angle
        delta_angle = self._delta_angle
        clockwise = self._clockwise
        arc_radius = self._arc_radius
        start_line_radius = self._start_line_radius
        end_line_radius = self._end_line_radius
        x = self._x
        y = self._y
        stroke_color = self._stroke_color
        stroke_width = self._stroke_width
        text_radius = self._text_radius
        font_size = self._font_size
        text_color = self._text_color
        scale_radii = self._scale_radii
        scale_text = self._scale_text
        scale_strokes = self._scale_strokes

        if not (math.isfinite(start_angle) and math.isfinite(delta_angle)):
            return

        end_angle = start_angle + delta_angle

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

        self._show_hand(cr, x, y, -start_angle, radius_scale*start_line_radius)
        self._show_hand(cr, x, y, -end_angle, radius_scale*end_line_radius)

        if clockwise:
            cr.arc(x, y, radius_scale*arc_radius, -start_angle, -end_angle)
        else:
            cr.arc_negative(x, y, radius_scale*arc_radius, -start_angle, -end_angle)

        cr.save()
        if scale_strokes:
            cr.identity_matrix()
        cr.set_source_rgba(*stroke_color)
        cr.set_line_width(stroke_width)
        cr.stroke()
        cr.restore()

        half_angle = (start_angle + end_angle) / 2
        cr.move_to(x, y)
        cr.rel_move_to(
            radius_scale*text_radius *  math.cos(half_angle),
            radius_scale*text_radius * -math.sin(half_angle),
        )

        cr.save()

        cr.set_source_rgba(*text_color)
        cr.set_font_size(font_size)

        if scale_text:
            cr.identity_matrix()

        text = '{:.1f}°'.format(math.degrees(math.fabs(delta_angle)))
        text_extents = cr.text_extents(text)

        cr.rel_move_to(-text_extents.x_bearing, -text_extents.y_bearing)
        cr.rel_move_to(-text_extents.width/2, -text_extents.height/2)
        cr.show_text(text)
        cr.fill()

        cr.restore()
Example #4
0
    def draw_with_hint(self, ctx: cairo.Context, x, y, layout, hint=''):
        if self.is_roomazi():
            hint = self.roomazi.hyphenize(hint)
        ctx.move_to(x, y)
        ctx.set_line_width(1)
        ctx.set_line_join(cairo.LineJoin.ROUND)
        scale = 0.4
        orig_x = x
        orig_y = y
        h = Keyboard.L * scale
        r = Keyboard.R * scale
        s = Keyboard.S * scale
        shift = list()
        shift_left = False
        shift_right = False
        alt = list()
        index_raw = 0
        fingers = list()
        for raw in layout:
            index_column = 0
            for column in raw:
                if column[1] == '⇧':
                    shift.append((x, y, column))
                if column[1] == '⌥':
                    alt.append((x, y, column))
                w = column[0] * scale
                color = self.get_key_color(index_column)
                if index_raw <= 0 or 4 <= index_raw:
                    color = (0x99, 0x99, 0x99)
                ctx.set_source_rgb(*[c / 255 for c in color])
                if self._is_uk_enter(column):
                    self.uk_enter(ctx, x, y, w, h, s, r)
                else:
                    self.round_rect(ctx, x + s, y + s, w - 2 * s, h - 2 * s, r)
                ctx.stroke()
                for c in hint:
                    if c in column[1]:
                        if index_raw < 4:
                            fingers.append(index_column)
                        if c == '\u3000':
                            c = "空白"
                        self._draw_key(ctx, x, y, w, h, s, r, c)
                    elif c in column[2]:
                        if index_raw < 4:
                            fingers.append(index_column)
                        self._draw_key(ctx, x, y, w, h, s, r, c)
                        if index_column <= 5:
                            shift_right = True
                        else:
                            shift_left = True
                x += w
                index_column += 1
            index_raw += 1
            x = orig_x
            y += h
        if shift_right:
            if 2 <= len(shift):
                self._draw_key(ctx, shift[1][0], shift[1][1],
                               shift[1][2][0] * scale, h, s, r, 'シフト')
            else:
                self._draw_key(ctx, shift[0][0], shift[0][1],
                               shift[0][2][0] * scale, h, s, r, 'シフト')
        if shift_left:
            self._draw_key(ctx, shift[0][0], shift[0][1],
                           shift[0][2][0] * scale, h, s, r, 'シフト')

        # draw fingers
        if 5 in fingers:
            fingers.append(4)
        if 6 in fingers:
            fingers.append(7)
        metrics = [(1, 25, 8), (2, 45, 10), (3, 60, 10), (4, 45, 10),
                   (7, 45, 10), (8, 60, 10), (9, 45, 10), (10, 25, 8)]
        x = orig_x - 100
        y = orig_y + 4.5 * Keyboard.L * scale
        for m in metrics:
            r = m[2]
            ctx.set_source_rgb(*[c / 255 for c in (0x99, 0x99, 0x99)])
            ctx.move_to(x, y)
            y -= m[1]
            ctx.line_to(x, y)
            ctx.arc(x + r, y, r, -180 * Keyboard.DEG, 0 * Keyboard.DEG)
            y += m[1]
            x += 2 * r
            ctx.line_to(x, y)
            ctx.stroke()
            if m[0] in fingers:
                color = self.get_key_color(m[0])
                ctx.set_source_rgb(*[c / 255 for c in color])
                ctx.arc(x - r, y - m[1] + 1, r * 0.8, 0 * Keyboard.DEG,
                        360 * Keyboard.DEG)
                ctx.fill()
            if m[0] != 4:
                x += 5
            else:
                ctx.set_source_rgb(*[c / 255 for c in (0x99, 0x99, 0x99)])
                # draw thumbs
                ctx.move_to(x, y)
                y += 30
                ctx.line_to(x, y)
                x += 20
                y -= 5
                ctx.line_to(x, y)
                ctx.arc(x, y + r, r, -90 * Keyboard.DEG, 90 * Keyboard.DEG)
                y += 2 * r
                x -= 20
                y += 5
                ctx.line_to(x, y)

                x = orig_x + 1500 * scale + 7
                y = orig_y + 4.5 * Keyboard.L * scale

                ctx.move_to(x, y)
                y += 30
                ctx.line_to(x, y)
                x -= 20
                y -= 5
                ctx.line_to(x, y)
                ctx.arc_negative(x, y + r, r, -90 * Keyboard.DEG,
                                 90 * Keyboard.DEG)
                y += 2 * r
                x += 20
                y += 5
                ctx.line_to(x, y)

                x = orig_x + 1500 * scale + 7

            y = orig_y + 4.5 * Keyboard.L * scale