Example #1
0
    def background(self, cr: cairo.Context):

        linear = cairo.LinearGradient(0, 0, .25, 1)
        linear.add_color_stop_rgb(0.0, *colors[0])
        linear.add_color_stop_rgb(0.4, *colors[5])
        linear.add_color_stop_rgb(1.0, *colors[6])

        cr.rectangle(0, 0, .5, 1)
        cr.set_source(linear)
        cr.fill()

        cr.rectangle(0.5, 0, 1, 1)

        linear = cairo.LinearGradient(1, 0, .75, 1)
        linear.add_color_stop_rgb(0.0, *colors[0])
        linear.add_color_stop_rgb(0.4, *colors[5])
        linear.add_color_stop_rgb(1.0, *colors[6])
        cr.set_source(linear)
        cr.fill()

        cr.move_to(.5, 0)  # lower left
        cr.rel_line_to(-.5, 1)
        cr.rel_line_to(1, 0)
        cr.close_path()

        radial = cairo.RadialGradient(0.5, 0.5, 0.1, 0.5, 0.5, 0.75)
        radial.add_color_stop_rgba(0, *colors[3], 0.7)
        radial.add_color_stop_rgba(.4, *colors[1], 0.5)
        radial.add_color_stop_rgba(1, *colors[2], 0.1)

        cr.set_source(radial)
        cr.fill()
Example #2
0
 def draw_precip_curve(
     self,
     context: cairo.Context,
     points: List[Tuple[int, int]],
     bottom: int,
     color,
     curviness: float = 7,
 ):
     # Draw the top curves
     for i, point in enumerate(points):
         if i == 0:
             context.move_to(*point)
         else:
             last_point = points[i - 1]
             context.curve_to(
                 last_point[0] + curviness,
                 last_point[1],
                 point[0] - curviness,
                 point[1],
                 point[0],
                 point[1],
             )
     # Draw the rest and fill
     context.line_to(points[-1][0], bottom)
     context.line_to(points[0][0], bottom)
     context.close_path()
     context.set_source_rgb(*color)
     context.fill()
Example #3
0
    def draw_triag(self, cr: cairo.Context, p):
        # p-> lower left coordinate of the triangle
        cr.move_to(*p)  # lower left

        cr.rel_line_to(2 * self.dx, 0)  # line to lower right
        cr.rel_line_to(-self.dx, -self.dy)
        cr.close_path()
Example #4
0
def draw_polyline(context: cairo.Context, polyline: symbols.Polyline) -> None:
    """draw a polyline"""

    if not polyline.lines:
        return

    # The gotchas for animation and joints will be handled by polyline_frac, not this.

    context.set_line_width(polyline.thickness)
    _set_color(context, polyline.color)

    if polyline.joint_type != '':
        context.set_line_join(polyline.joint_type)

    context.move_to(polyline.lines[0].start[0], polyline.lines[0].start[1])

    if polyline.closed:
        for line in polyline.lines[:-1]:
            context.line_to(line.end[0], line.end[1])
        context.close_path()
    else:
        for line in polyline.lines:
            context.line_to(line.end[0], line.end[1])

    context.stroke()
    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)
    def do_render(self, model: Dazzle.GraphModel, x_begin: int, x_end: int,
                  y_begin: float, y_end: float, cairo_context: cairo.Context,
                  area: cairo.RectangleInt) -> None:
        model_iter = Dazzle.GraphModelIter()
        cairo_context.save()

        if model.get_iter_first(model_iter):
            chunk = area.width / (model.props.max_samples - 1) / 2.0
            last_x = self._calc_x(model_iter, x_begin, x_end, area.width)
            last_y = float(area.height)

            cairo_context.move_to(last_x, area.height)

            while Dazzle.GraphModel.iter_next(model_iter):
                x = self._calc_x(model_iter, x_begin, x_end, area.width)
                y = self._calc_y(model_iter, y_begin, y_end, area.height,
                                 self._column)

                cairo_context.curve_to(last_x + chunk, last_y, last_x + chunk,
                                       y, x, y)

                last_x = x
                last_y = y

        cairo_context.set_line_width(self._line_width)
        cairo_context.set_source_rgba(self._stacked_color_rgba.red,
                                      self._stacked_color_rgba.green,
                                      self._stacked_color_rgba.blue,
                                      self._stacked_color_rgba.alpha)
        cairo_context.rel_line_to(0, area.height)
        cairo_context.stroke_preserve()
        cairo_context.close_path()
        cairo_context.fill()

        if model.get_iter_first(model_iter):
            chunk = area.width / (model.props.max_samples - 1) / 2.0
            last_x = self._calc_x(model_iter, x_begin, x_end, area.width)
            last_y = float(area.height)

            cairo_context.move_to(last_x, last_y)

            while Dazzle.GraphModel.iter_next(model_iter):
                x = self._calc_x(model_iter, x_begin, x_end, area.width)
                y = self._calc_y(model_iter, y_begin, y_end, area.height,
                                 self._column)

                cairo_context.curve_to(last_x + chunk, last_y, last_x + chunk,
                                       y, x, y)

                last_x = x
                last_y = y

        cairo_context.set_source_rgba(self._stroke_color_rgba.red,
                                      self._stroke_color_rgba.green,
                                      self._stroke_color_rgba.blue,
                                      self._stacked_color_rgba.alpha)
        cairo_context.stroke()
        cairo_context.restore()
Example #7
0
def draw_poly(poly: RegularPolygon, ctx: cairo.Context):
    ctx.save()
    v = poly.vertices()
    ctx.move_to(v[0][0], v[0][1])
    for i in range(1, len(v)):
        ctx.line_to(v[i][0], v[i][1])
    ctx.close_path()
    ctx.stroke()
    ctx.restore()
def draw_one_rect(ctx: cairo.Context, rect: PColoredRectangle) -> None:
    ctx.move_to(rect.x, rect.y)
    x2 = rect.x + rect.width
    y2 = rect.y + rect.height
    ctx.line_to(x2, rect.y)
    ctx.line_to(x2, y2)
    ctx.line_to(rect.x, y2)
    ctx.close_path()
    ctx.set_source_rgba(rect.r, rect.g, rect.b, rect.a)
    ctx.fill()
Example #9
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()
Example #10
0
    def draw(self, cr: cairo.Context, vp_matrix: np.ndarray):

        for i in range(len(self.normalized_vertices)):
            proximo_vp = self.normalized_vertices[i] @ vp_matrix
            cr.line_to(proximo_vp.x, proximo_vp.y)
        cr.close_path()
        if self.filled:
            cr.stroke_preserve()
            cr.fill()
        else:
            cr.stroke()
Example #11
0
    def draw(self, cr: Context, vp_matrix: np.ndarray):
        for v in self.vertices_ndc:
            next_vp = v @ vp_matrix
            cr.line_to(next_vp.x, next_vp.y)
        cr.close_path()

        if self.filled:
            cr.stroke_preserve()
            cr.fill()
        else:
            cr.stroke()
Example #12
0
 def _polygon(self, ctx: cairo.Context, points, color, outline=None):
     ctx.new_path()
     for point in points:
         ctx.line_to(*point)
     ctx.close_path()
     ctx.set_source_rgba(*color)
     if outline is not None:
         ctx.fill_preserve()
         ctx.set_source_rgba(*outline)
         ctx.set_line_width(1)
         ctx.stroke()
     else:
         ctx.fill()
Example #13
0
 def draw_highlight(self, _area: Gtk.DrawingArea, context: Context) -> None:
     if self.current_region and self.t:
         poly: Polygon = self.current_region.poly
         poly = poly.buffer(1, single_sided=True)
         # TODO: 239, 134, 97, 0.7 taken from gtk.css, possible to get it from os????
         context.set_source_rgba(239 / 255.0, 134 / 255.0, 97 / 255.0, 0.7)
         context.set_line_width(
             clamp(self.configurators['scale'].get_exp() * 12, 0.5, 5))
         context.new_path()
         # Nice idea, but didnt work with scrolling: context.set_matrix(Matrix(1.0/self.t.scale, 0, 0, 1.0/self.t.scale, -self.t.tx, -self.t.ty))
         for coord in poly.exterior.coords:
             context.line_to(*self.t.inverse(*coord))
         context.close_path()
         context.stroke()
Example #14
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()
Example #15
0
 def draw_on(self, ctx: cairo.Context):
     for i in range(len(self.points) - 1):
         ctx.line_to(*self.points[i + 1])
     ctx.close_path()
Example #16
0
class Canvas:
    def __init__(self,
                 width: int,
                 height: Optional[int] = None,
                 *,
                 normalise: bool = True):
        if height is None:
            height = width
        self._width = width
        self._height = height
        self._surface = ImageSurface(FORMAT_ARGB32, width, height)
        self._context = Context(self._surface)
        self._normalise = normalise
        if self._normalise:
            self.scale(self._width, self._height)

    @property
    def width(self) -> int:
        return self._width if not self._normalise else 1

    @property
    def height(self) -> int:
        return self._height if not self._normalise else 1

    # TODO depreciate
    @property
    def context(self) -> Context:  # pragma: no cover
        return self._context

    def save(self) -> None:
        self._context.save()

    def restore(self) -> None:
        self._context.restore()

    # Transformation
    def rotate(self, angle: float) -> None:
        self._context.rotate(angle)

    def translate(self, x: float, y: float) -> None:
        self._context.translate(x, y)

    def scale(self, width: int, height: int) -> None:
        self._context.scale(width, height)

    def set_line_width(self, width: float) -> None:
        self._context.set_line_width(width)

    # Colour functionality
    def set_colour(self, colour: Colour) -> None:
        self._context.set_source_rgba(colour.red, colour.blue, colour.green,
                                      colour.alpha)

    def set_grey(self, colour_value: float, alpha: float = 1) -> None:
        colour = Colour(*(colour_value, ) * 3, alpha)
        self.set_colour(colour)

    def set_black(self) -> None:
        self.set_colour(BLACK)

    def set_white(self) -> None:
        self.set_colour(WHITE)

    def set_background(self, colour: Colour) -> None:
        self._context.rectangle(0, 0, self.width, self.height)
        self.set_colour(colour)
        self._context.fill()

    def set_line_cap(self, line_cap: LineCap) -> None:
        self._context.set_line_cap(line_cap.value)

    def set_line_join(self, line_join: LineJoin) -> None:
        self._context.set_line_join(line_join.value)

    def set_fill_rule(self, file_rule: FillRule) -> None:
        self._context.set_fill_rule(file_rule.value)

    # Render methods
    def fill(self, preserve: bool = False) -> None:
        if not preserve:
            self._context.fill()
        else:
            self._context.fill_preserve()

    def stroke(self, preserve: bool = False) -> None:
        if not preserve:
            self._context.stroke()
        else:
            self._context.stroke_preserve()

    def clip(self) -> None:
        self._context.clip()

    def _draw_path(self, path: Iterable[Point], close_path: bool) -> None:
        self._context.new_sub_path()
        for p in path:
            self._context.line_to(*p)
        if close_path:
            self._context.close_path()

    def draw_path(self,
                  path: Iterable[PointType],
                  close_path: bool = False) -> None:
        points = (p if isinstance(p, Point) else Point(*p) for p in path)
        self._draw_path(points, close_path)

    def draw_polygon(self, polygon: Polygon) -> None:
        self._draw_path(polygon.points, close_path=True)

    def draw_circle(self,
                    circle: Circle,
                    fill: bool = False,
                    stroke: bool = True) -> None:
        self._context.new_sub_path()
        self._context.arc(*circle.centre, circle.radius, 0, 2 * pi)

    def write_to_png(self, file_name: str) -> None:
        self._surface.write_to_png(file_name)
Example #17
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()