Esempio n. 1
0
class Plot(object):
    red = (1., 0., 0.)
    green = (0., 1., 0.)
    blue = (0., 0., 1.)
    yellow = (1., 1., 0.)
    cyan = (0., 1., 1.)
    magenta = (1., 0., 1.)

    def __init__(self, width, height):
        from cairocffi import SVGSurface, Context
        self.plot_id = next(_debug_generator)
        self._surface = SVGSurface("debug_plot-%05d.svg" % self.plot_id, width,
                                   height)
        self._ctx = Context(self._surface)
        self._ctx.set_source_rgb(0., 0., 0.)
        self._ctx.paint()

    def line(self, line, color):
        ctx = self._ctx
        ctx.move_to(line.p1.x, line.p1.y)
        ctx.line_to(line.p2.x, line.p2.y)
        ctx.set_source_rgb(*color)
        ctx.stroke()

    def circle(self, center, radius, stroke_color, fill_color=None):
        ctx = self._ctx
        ctx.new_sub_path()
        ctx.arc(center.x, center.y, radius, 0, math.pi * 2)
        ctx.set_source_rgb(*stroke_color)
        if fill_color:
            ctx.stroke_preserve()
            ctx.set_source_rgb(*fill_color)
            ctx.fill()
        else:
            ctx.stroke()
 def _draw_stroke(self, ctx: Context, geom: Union[Polygon, MultiPolygon]):
     if isinstance(geom, MultiPolygon):
         for sub_geom in geom.geoms:
             self._draw_stroke(ctx, sub_geom)
         return
     CairoHelper.draw_polygon(ctx, geom)
     ctx.stroke()
Esempio n. 3
0
def _(d: Line, ctx: cairo.Context, scale: float):
    ctx.save()
    ctx.move_to(d.x0 * scale, d.y0 * scale)
    ctx.line_to(d.x1 * scale, d.y1 * scale)
    ctx.stroke()
    # ctx.fill()
    ctx.restore()
    def _draw_railway(self, ctx: Context, line_string: LineString):
        CairoHelper.draw_line_string(ctx, line_string)

        # Todo: Buffer the linestring outwards
        # ShapelyHelper.buffer_linestring()

        ctx.stroke()
Esempio n. 5
0
 def _draw_stroke(self, ctx: Context, geom: Union[LineString,
                                                  MultiLineString]):
     if isinstance(geom, MultiLineString):
         for sub_geom in geom.geoms:
             self._draw_stroke(ctx, sub_geom)
         return
     CairoHelper.draw_line_string(ctx, geom)
     ctx.stroke()
Esempio n. 6
0
 def __init__(self, width, height):
     from cairocffi import SVGSurface, Context
     self.plot_id = next(_debug_generator)
     self._surface = SVGSurface("debug_plot-%05d.svg" % self.plot_id, width,
                                height)
     self._ctx = Context(self._surface)
     self._ctx.set_source_rgb(0., 0., 0.)
     self._ctx.paint()
Esempio n. 7
0
 def paint_children(self, ctx: Context):
     for child in self.children:
         ctx.save()
         ctx.translate(*child.position(Anchor.TOP_LEFT))
         ctx.rectangle(0, 0, *child.size)
         ctx.clip()
         child.paint(ctx)
         ctx.restore()
Esempio n. 8
0
 def set(self, ctx: Context):
     """
     Set this font to get used on the given context.
     :param ctx:
     """
     ctx.select_font_face(self.name,
                          cairo.FONT_SLANT_ITALIC if self.italic else cairo.FONT_SLANT_NORMAL,
                          cairo.FONT_WEIGHT_BOLD if self.bold else cairo.FONT_WEIGHT_NORMAL)
     ctx.set_font_size(self.size)
Esempio n. 9
0
    def draw_line_string(ctx: Context, line_string: LineString):
        start = True
        for x, y in line_string.coords:
            if start:
                ctx.move_to(x, y)
            else:
                ctx.line_to(x, y)

            start = False
Esempio n. 10
0
 def paint_scale_background(self, ctx: Context):
     cpu_count = Global.system_data.cpu_count
     for i in range(cpu_count):
         if i % 2:
             ctx.set_source_rgba(*Color.GRAY33)
         else:
             ctx.set_source_rgba(*Color.GRAY50)
         ctx.move_to(0, self.height - self.height / cpu_count * i)
         ctx.line_to(self.width, self.height - self.height / cpu_count * i)
         ctx.stroke()
Esempio n. 11
0
    def create_graphics(self, surface: Surface):
        if surface is None:
            raise ValueError("Argument 'surface' is required.")

        g = Graphics(surface)

        g.set_antialias(ANTIALIAS_BEST)
        g.set_font_options(self.font_options)

        return g
Esempio n. 12
0
def _rectangle_path(
        context: cairocffi.Context,
        rectangle: pangocffi.Rectangle
):
    x, y, width, height = _convert_rectangle_to_pixels(rectangle)
    context.move_to(x, y)
    context.line_to(x + width, y)
    context.line_to(x + width, y + height)
    context.line_to(x, y + height)
    context.line_to(x, y)
Esempio n. 13
0
 def paint(self, ctx: Context):
     """
     Renders this widget.
     :param ctx: Cairo context.
     """
     if self.background:
         ctx.set_source_rgba(*self.background)
         self.paint_background(ctx)
     ctx.set_source_rgba(*self.foreground)
     self.paint_foreground(ctx)
     self.dirty = False
Esempio n. 14
0
    def draw_background(self, g: Graphics, component: T, color: RGBA) -> None:
        area = component.bounds

        if area.width == 0 or area.height == 0:
            return

        g.set_source_rgba(color.r, color.g, color.b, color.a)

        self.draw_rect(g, area, 8)

        g.fill()
Esempio n. 15
0
def _show_label(
        context: cairocffi.Context,
        position: Tuple[float, float],
        width: float,
        text: str
):
    context.translate(position[0], position[1])
    label = pangocairocffi.create_layout(context)
    label.set_width(pangocffi.units_from_double(width))
    label.set_alignment(pangocffi.Alignment.LEFT)
    label.set_markup('<span font-family="sans-serif">%s</span>' % text)
    pangocairocffi.show_layout(context, label)
    context.translate(-position[0], -position[1])
Esempio n. 16
0
    def draw(self, ctx: Context, outline: Union[Polygon, MultiPolygon]):
        if isinstance(outline, MultiPolygon):
            shadow_line_strings = []
            for sub_outline in outline.geoms:
                shadow_line_string = self.draw(ctx, sub_outline)
                shadow_line_strings.append(shadow_line_string)
            return shadow_line_strings
        buffered_outline = outline.buffer(-self.outline_line_width / 2, cap_style=3, join_style=2)

        shadow_line_strings = self._get_shadow_lines(buffered_outline)
        for shadow_line_string in shadow_line_strings:
            CairoHelper.draw_line_string(ctx, shadow_line_string)
            ctx.stroke()
        pass
Esempio n. 17
0
def render_cluster_glyph_items(
        ctx: cairocffi.Context,
        layout: pangocffi.Layout
):
    """
    Renders each cluster within a layout with a unique rotation and color.

    Warning: Does not support bidirectional text.

    :param ctx:
        a Cairo context
    :param layout:
        a Pango layout
    """
    layout_run_iter = layout.get_iter()
    layout_cluster_iter = layout.get_iter()
    layout_text = layout.get_text()

    alternate = False
    while True:

        layout_run = layout_run_iter.get_run()
        layout_line_baseline = layout_run_iter.get_baseline()

        if layout_run is None:
            if not layout_run_iter.next_run():
                break
            continue

        clusters = get_clusters_from_glyph_item(layout_run, layout_text)
        for cluster in clusters:
            cluster_extents = layout_cluster_iter.get_cluster_extents()[1]
            layout_cluster_iter.next_cluster()
            alternate = not alternate
            ctx.set_source_rgba(0.5, 0, 1 if alternate else 0.5, 0.9)
            ctx.save()
            ctx.translate(
                pangocffi.units_to_double(cluster_extents.x),
                pangocffi.units_to_double(layout_line_baseline)
            )
            ctx.rotate(-0.05 if alternate else 0.05)
            pangocairocffi.show_glyph_item(
                ctx,
                layout_text,
                cluster
            )
            ctx.restore()

        if not layout_run_iter.next_run():
            break
Esempio n. 18
0
def _coordinate_path(
        context: cairocffi.Context,
        point: Tuple[int, int],
        radius: float = 1
):
    for i in range(0, 8):
        p_x = pangocffi.units_to_double(point[0]) + \
            math.sin(i/4 * math.pi) * radius
        p_y = pangocffi.units_to_double(point[1]) + \
            math.cos(i/4 * math.pi) * radius
        if i == 0:
            context.move_to(p_x, p_y)
        else:
            context.line_to(p_x, p_y)
Esempio n. 19
0
 def set_source_rgb(self,
                    colour: Union[ColorType, List[ColorType]],
                    ctx: cairocffi.Context = None):
     # If an alternate context is not provided then we draw to the
     # drawer's default context
     if ctx is None:
         ctx = self.ctx
     if isinstance(colour, list):
         if len(colour) == 0:
             # defaults to black
             ctx.set_source_rgba(*utils.rgb("#000000"))
         elif len(colour) == 1:
             ctx.set_source_rgba(*utils.rgb(colour[0]))
         else:
             linear = cairocffi.LinearGradient(0.0, 0.0, 0.0, self.height)
             step_size = 1.0 / (len(colour) - 1)
             step = 0.0
             for c in colour:
                 rgb_col = utils.rgb(c)
                 if len(rgb_col) < 4:
                     rgb_col[3] = 1
                 linear.add_color_stop_rgba(step, *rgb_col)
                 step += step_size
             ctx.set_source(linear)
     else:
         ctx.set_source_rgba(*utils.rgb(colour))
Esempio n. 20
0
    def draw(self, ctx: Context):

        if not self.canvas_set:
            raise Exception("Canvas size not set!")

        top_left = (0, 0)
        top_right = (self.canvas_width, 0)
        bottom_left = (0, self.canvas_height)
        bottom_right = (self.canvas_width, self.canvas_height)

        canvas = Polygon(
            [top_left, top_right, bottom_right, bottom_left, top_left])

        ctx.set_source_rgba(*self.color)
        CairoHelper.draw_polygon(ctx, canvas)
        ctx.fill()
Esempio n. 21
0
def test_layout_clusters_get_max_logical_extent():
    surface = SVGSurface(None, 100, 100)
    cairo_context = Context(surface)

    layout_1 = pangocairocffi.create_layout(cairo_context)
    layout_1.set_markup('Text with one line')
    layout_1_clusters = LayoutClusters(layout_1)
    extent_1 = layout_1_clusters.get_max_logical_extent()

    layout_2 = pangocairocffi.create_layout(cairo_context)
    layout_2.set_markup('text with\ntwo lines')
    layout_2_clusters = LayoutClusters(layout_2)
    extent_2 = layout_2_clusters.get_max_logical_extent()

    assert extent_1.x == 0
    assert extent_1.y == 0
    assert extent_1.width > 0
    assert extent_1.height > 0

    assert extent_2.x == extent_1.x
    assert extent_2.y == extent_1.y
    assert extent_1.width != extent_2.width
    assert extent_1.height * 2 == extent_2.height

    surface.finish()
Esempio n. 22
0
 def _create_real_surface(self,
                          filename: str,
                          width: int = 100,
                          height: int = 100) -> Tuple[Surface, Context]:
     surface = SVGSurface('tests/output/text_path_%s' % filename, width,
                          height)
     cairo_context = Context(surface)
     return surface, cairo_context
Esempio n. 23
0
def _show_layout_line_logical_extents(
        context: cairocffi.Context,
        layout: pangocffi.Layout
):
    layout_iter = layout.get_iter()
    context.set_line_width(0.5)
    context.set_dash([1, 1])
    alternate = True
    while True:
        alternate = not alternate
        extents = layout_iter.get_line_extents()
        context.set_source_rgba(0, 0, 1 if alternate else 0.5, 0.9)
        _rectangle_path(context, extents[1])
        context.stroke()
        _coordinate_path(context, (extents[1].x, extents[1].y))
        context.fill()

        if not layout_iter.next_run():
            break
Esempio n. 24
0
    def paint_foreground(self, ctx: Context):
        layout = self.font.get_layout(self.text, ctx, self.foreground, self.escape)
        if self.h_alignment == TextWidget.HAlignment.LEFT:
            layout.set_alignment(Alignment.LEFT)
        else:
            layout.set_width(round(self.width * 1000))
            if self.h_alignment == TextWidget.HAlignment.CENTER:
                layout.set_alignment(Alignment.CENTER)
            elif self.h_alignment == TextWidget.HAlignment.RIGHT:
                layout.set_alignment(Alignment.RIGHT)

        y = -layout.get_extents()[0].y / 1000
        if self.v_alignment == TextWidget.VAlignment.BOTTOM:
            y += self.height - layout.get_extents()[0].height / 1000
        elif self.v_alignment == TextWidget.VAlignment.CENTER:
            y += (self.height - layout.get_extents()[0].height / 1000) / 2

        ctx.move_to(0, y)
        pangocairo.show_layout(ctx, layout)
Esempio n. 25
0
    def draw(self, g: Graphics) -> None:
        if self.visible:
            g.save()

            (dx,
             dy) = self.parent.map(lambda p: p.location).value_or(Point(0, 0))
            (cx, cy, cw, ch) = self.ui.clip_bounds(self).tuple

            g.translate(dx, dy)
            g.rectangle(cx, cy, cw, ch)

            g.clip()

            try:
                self.draw_component(g)
            except BaseException as e:
                self.error_handler(e)

            g.restore()
    def draw(self, context: Context):
        text_path_glyph_items = self._compute_text_path_glyph_items()
        for text_path_glyph_item in text_path_glyph_items:
            glyph_position = text_path_glyph_item.position
            glyph_rotation = text_path_glyph_item.rotation

            context.save()
            context.translate(glyph_position.x, glyph_position.y)
            context.rotate(glyph_rotation)
            show_glyph_item(context, self._layout_text,
                            text_path_glyph_item.glyph_item)
            context.restore()
Esempio n. 27
0
def transform(
    ctx: cairo.Context,
    point: Tuple[float, float],
    rotation: float = None,
    scale_x=1.0,
    scale_y=1.0,
):
    ctx.translate(point[0], point[1])
    if rotation is not None:
        ctx.rotate(math.radians(rotation))
    if scale_x != 1.0 or scale_y != 1.0:
        ctx.scale(sx=scale_x, sy=scale_y)
    ctx.translate(-point[0], -point[1])
Esempio n. 28
0
def label_train_interfaces(ctx: cairo.Context,
                           train: trains.Train,
                           radius_factors=1,
                           broken_spaces: Sequence = None):
    spaces, brokens = break_spaces(train.spaces, broken_spaces)
    radius_factors = np.broadcast_to(radius_factors, (len(train.interfaces), ))

    ctx.save()
    ctx.translate(0, spaces[0])
    for interface, space, radius_factor in zip(train.interfaces, spaces[1:],
                                               radius_factors):
        label_interface(ctx, interface, radius_factor)
        ctx.translate(0, space)
    ctx.restore()
Esempio n. 29
0
    def draw_component(self, g: Graphics, component: Canvas) -> None:
        super().draw_component(g, component)

        if component.image == Nothing:
            return

        image = component.image.unwrap()
        padding = component.resolve_insets(StyleKeys.Padding).value_or(
            Insets(0, 0, 0, 0)) + component.padding

        (x, y, w, h) = component.bounds.tuple

        bounds = Bounds(x + padding.left, y + padding.top,
                        max(w - padding.left - padding.right, 0),
                        max(h - padding.top - padding.bottom, 0))

        (iw, ih) = image.size.tuple
        (w, h) = bounds.size.tuple

        if iw == 0 or ih == 0 or w == 0 or h == 0:
            return

        (x, y) = bounds.location.tuple

        sw = w / iw
        sh = h / ih

        sx = x / sw
        sy = y / sh

        g.scale(sw, sh)
        g.set_source_surface(image.surface, sx, sy)
        g.paint()
Esempio n. 30
0
def render_run_glyph_items(
        ctx: cairocffi.Context,
        layout: pangocffi.Layout
) -> None:
    """
    Renders each layout run within a layout with a unique rotation and color.

    :param ctx:
        a Cairo context
    :param layout:
        a Pango layout
    """
    layout_iter = layout.get_iter()
    layout_text = layout.get_text()

    alternate = False
    while True:
        layout_run = layout_iter.get_run()
        layout_run_extents = layout_iter.get_run_extents()[1]
        layout_line_baseline = layout_iter.get_baseline()

        if layout_run is None:
            if not layout_iter.next_run():
                break
            continue

        alternate = not alternate
        ctx.set_source_rgba(0, 0.5, 1 if alternate else 0.5, 0.9)
        ctx.save()
        ctx.translate(
            pangocffi.units_to_double(layout_run_extents.x),
            pangocffi.units_to_double(layout_line_baseline)
        )
        ctx.rotate(0.05 if alternate else -0.05)
        pangocairocffi.show_glyph_item(ctx, layout_text, layout_run)
        ctx.restore()

        if not layout_iter.next_run():
            break
    def __draw_sector (self: 'HueSatWheelWidget', cr: cairocffi.Context,
                       center_x: float, center_y: float) -> None:
        cr.save ()
        cr.set_line_width (1)

        offset = self.rotation

        for idx, sector in enumerate (self.sector[0]):
            half_angle = 2 * numpy.pi * sector / 2
            offset += self.sector[1][idx] * 2 * numpy.pi
            cr.set_source_rgba (0, 0, 0, 1)
            cr.move_to (center_x, center_y)
            cr.arc (center_x, center_y, (self.size - 2) / 2.,
                    offset - half_angle, half_angle + offset)
            cr.line_to (center_x, center_y)
            cr.stroke_preserve ()
            cr.set_source_rgba (0, 0, 0, 0.25)
            cr.fill ()

        cr.restore ()
    def __draw_ring (self: 'HueSatWheelWidget', cr: cairocffi.Context,
                     width: int, height: int, center_x: float, center_y: float,
                     outer: float, inner: float) -> None:
        self.__redraw = False
        stride = cairocffi.ImageSurface.format_stride_for_width (cairocffi.FORMAT_ARGB32, width)
        buf = numpy.empty (int (height * stride), dtype = numpy.uint8)

        for y in range (height):
            idx = y * width * 4

            dy = -(y - center_y)

            for x in range (width):
                dx = x - center_x

                dist = dx * dx + dy * dy

                angle = math.atan2 (dy, dx)

                if angle < 0:
                    angle += 2 * numpy.pi

                hue = angle / (2 * numpy.pi)

                hue_idx = int ((angle + 2 * numpy.pi / 3) / (2 * numpy.pi) * 255)
                hue_idx = hue_idx % 256

                if dist < ((inner - 1) ** 2) * (1 - self.__hist[255 - hue_idx]) or \
                   dist > ((outer + 1) ** 2):
                    buf[idx + 0] = 0
                    buf[idx + 1] = 0
                    buf[idx + 2] = 0
                    buf[idx + 3] = 0
                    idx += 4
                    continue

                r, g, b = colorsys.hsv_to_rgb (hue, 1.0, 1.0)
                a = 255

                buf[idx + 0] = int (math.floor (r * 255 + 0.5))
                buf[idx + 1] = int (math.floor (g * 255 + 0.5))
                buf[idx + 2] = int (math.floor (b * 255 + 0.5))
                buf[idx + 3] = a
                idx += 4

        source = cairocffi.ImageSurface.create_for_data (
            memoryview (buf), cairocffi.FORMAT_ARGB32, width, height, stride
        )

        fg_color = self.get_style_context ().get_color (Gtk.StateFlags.NORMAL)

        cr.save ()

        cr.set_source_rgba (0, 0, 0, 0)
        cr.paint ()

        cr.set_source_surface (source, 0, 0)
        cr.paint ()

        cr.set_line_width (1)
        cr.new_path ()
        cr.set_source_rgba (*list (fg_color))

        cr.arc (center_x, center_y, (self.size - 4) / 2. - self.ring_width,
                0, 2 * numpy.pi)
        cr.stroke ()

        cr.arc (center_x, center_y, (self.size - 2) / 2, 0, 2 * numpy.pi)
        cr.stroke ()

        cr.arc (center_x, center_y, 5, 0, 2 * numpy.pi)
        cr.fill ()

        cr.restore ()