Example #1
0
def export_svg(fn, paths, size, line_with=0.1, scale_factor=None):

  from cairo import SVGSurface, Context
  from numpy import array
  from ddd import spatial_sort_2d as sort

  if not scale_factor:
    scale_factor = size

  one = 1.0/size
  s = SVGSurface(fn, size, size)
  c = Context(s)

  c.set_line_width(0.1)

  paths = sort(paths)

  for path in paths:
    path *= scale_factor

    c.new_path()
    c.move_to(*path[0,:])
    for p in path[1:]:
      c.line_to(*p)
    c.stroke()

  c.save()
Example #2
0
def export_svg(fn, paths, size, line_with=0.1, scale_factor=None):

    from cairo import SVGSurface, Context
    from .ddd import spatial_sort_2d as sort

    if not scale_factor:
        scale_factor = size

    s = SVGSurface(fn, size, size)
    c = Context(s)

    c.set_line_width(0.1)

    paths = sort(paths)

    for path in paths:
        path *= scale_factor

        c.new_path()
        c.move_to(*path[0, :])
        for p in path[1:]:
            c.line_to(*p)
        c.stroke()

    c.save()
Example #3
0
def draw_circular_roman(
    ctx: cairo.Context,
    rng: Generator,
    pos_x: float,
    pos_y: float,
    radius_outer: float,
    radius_inner: float,
):
    chunks = rng.integers(6, 16)
    _calendar_base(ctx, pos_x, pos_y, radius_outer, radius_inner, chunks)

    ctx.select_font_face("Noto Sans Symbols")
    font_size = 0.8 * (radius_outer - radius_inner)
    ctx.set_font_size(font_size)

    angle_offset = pi / chunks
    for i, (x, y) in enumerate(
            points_along_arc(
                pos_x,
                pos_y,
                (radius_inner + radius_outer) / 2.0,
                angle_offset,
                angle_offset + tau,
                chunks,
            ),
            1,
    ):
        with translation(ctx, x, y), rotation(ctx, (i * tau / chunks) +
                                              (pi / 2) - angle_offset):
            roman = int_to_roman(i)
            extents = ctx.text_extents(roman)

            ctx.move_to(-1 * extents.width / 2.0, extents.height / 2.0)
            ctx.show_text(roman)
            ctx.new_path()
Example #4
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()
Example #5
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 #6
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 #7
0
def export_svg(fn, paths, w, h, line_width=0.1):

    from cairo import SVGSurface, Context

    s = SVGSurface(fn, w, h)
    c = Context(s)

    c.set_line_width(line_width)

    for path in paths:

        c.new_path()
        c.move_to(*path[0, :])
        for p in path[1:]:
            c.line_to(*p)
        c.stroke()

    c.save()
Example #8
0
def export_svg(fn, paths, w, h, line_width=0.1):

  from cairo import SVGSurface, Context

  s = SVGSurface(fn, w, h)
  c = Context(s)

  c.set_line_width(line_width)

  for path in paths:

    c.new_path()
    c.move_to(*path[0,:])
    for p in path[1:]:
      c.line_to(*p)
    c.stroke()

  c.save()
Example #9
0
def _calendar_mapped(
    ctx: cairo.Context,
    rng: Generator,
    pos_x: float,
    pos_y: float,
    radius_outer: float,
    radius_inner: float,
    mapping: Sequence[str],
    font_family: str = "Noto Sans Symbols",
):
    chunks = rng.integers(6, min(len(mapping), 24))
    _calendar_base(ctx, pos_x, pos_y, radius_outer, radius_inner, chunks)

    ctx.select_font_face(font_family)
    font_size = 0.8 * (radius_outer - radius_inner)
    ctx.set_font_size(font_size)

    symbols = rng.choice(mapping, size=chunks, replace=False)

    angle_offset = pi / chunks
    for i, (x, y) in enumerate(
            points_along_arc(
                pos_x,
                pos_y,
                (radius_inner + radius_outer) / 2.0,
                angle_offset,
                angle_offset + tau,
                chunks,
            ),
            1,
    ):
        with translation(ctx, x, y), rotation(ctx, (i * tau / chunks) +
                                              (pi / 2) - angle_offset):
            symbol = symbols[i - 1]
            extents = ctx.text_extents(symbol)

            ctx.move_to(-1 * extents.width / 2.0, extents.height / 2.0)
            ctx.show_text(symbol)
            ctx.new_path()
Example #10
0
    def _do_draw(self, _, cr: cairo.Context):
        height = self.get_allocated_height()
        timeline_canvas = self.timeline_canvas

        # Show a guiding line under the mouse
        if self.current_moused_datetime is not None:
            timeline_x = timeline_canvas.timeline_helper.datetime_to_pixel(
                self.current_moused_datetime)

            cr.set_source_rgb(0.55, 0.55, 0.55)
            cr.new_path()
            cr.move_to(timeline_x, 0)
            cr.line_to(timeline_x, height)
            cr.stroke()

            current_guidingline_rectangle = cairo.RectangleInt(
                int(timeline_x) - 2, 0, 4, height)
            self.dirty_rectangles.append(current_guidingline_rectangle)

        # Highlight the hovered over entry
        moused_entry = None if self.moused_over_entity is None else self.moused_over_entity.entry
        if type(moused_entry) is LoggedEntry:
            le = self.moused_over_entity
            cr.set_source_rgba(0.7, 0.7, 0.7, 0.2)
            cr.rectangle(le.start_x, timeline_canvas.le_start_y, le.width,
                         timeline_canvas.timeline_height)
            cr.fill()
        elif type(moused_entry) is TaggedEntry:
            te = self.moused_over_entity
            cr.set_source_rgba(0.7, 0.7, 0.7, 0.2)
            cr.rectangle(te.start_x, timeline_canvas.te_start_y, te.width,
                         timeline_canvas.timeline_height)
            cr.fill()

        # Show the tooltip
        if self.tooltip_attributes is not None:
            self._show_details_tooltip(self.tooltip_attributes, cr)
        return True
        ctx.move_to(outline.points[start][0],outline.points[start][1])
        for j in range(start, end+1):
            point = outline.points[j]
            ctx.line_to(point[0],point[1])
        #back to origin
        ctx.line_to(outline.points[start][0], outline.points[start][1])
        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)
Example #12
0
    def _do_draw(self, _, cr: cairo.Context):
        # Get the size
        drawing_area_height = self.get_allocated_height()
        canvas_width = self.get_allocated_width()

        clip_start_x, _, clip_stop_x, _ = cr.clip_extents()

        # Show the activity as a background for the time area
        for ae in self.visible_activity_entries:
            if ae.stop_x < clip_start_x or clip_stop_x < ae.start_x:
                continue

            r, g, b = ae.color
            cr.set_source_rgb(r, g, b)
            cr.rectangle(ae.start_x, 0, ae.width, drawing_area_height)
            cr.fill()

        # Draw the hour lines
        cr.set_font_size(16)
        cr.set_source_rgb(0.35, 0.35, 0.35)
        cr.rectangle(0, 0, canvas_width,
                     self.guidingline_on_timeline_start + 10)
        cr.fill()
        for timeline_timeline in self.timeline_timelines:
            # Hour line
            hx = timeline_timeline.x
            cr.set_source_rgb(0.7, 0.7, 0.7)
            cr.new_path()
            cr.move_to(hx, self.guidingline_on_timeline_start)
            cr.line_to(hx, self.guidingline_on_timeline_start + 10)
            cr.stroke()

            # Hour text
            time = timeline_timeline.time
            if time.minute == 0:
                cr.set_source_rgb(0.9, 0.9, 0.3)
            else:
                cr.set_source_rgb(0.2, 0.8, 1)

            tx, hour_text_width = timeline_timeline.text_extents
            cr.move_to(hx - tx - (hour_text_width / 2),
                       self.time_guidingline_text_height)
            cr.show_text(timeline_timeline.text)

        # Draw the rectangles for the entries by colors
        for color, drawing_entries in self.timeline_entries_by_color.items():
            cr.set_source_rgb(*color)
            for drawing_entry in drawing_entries:
                if drawing_entry.stop_x < clip_start_x or clip_stop_x < drawing_entry.start_x:
                    continue
                cr.rectangle(drawing_entry.start_x, drawing_entry.start_y,
                             drawing_entry.width, drawing_entry.height)
            cr.fill()

        # The marker for the logged entries
        cr.set_source_rgb(0.3, 0.3, 0.8)
        for le in self.visible_logged_entries:
            if le.stop_x < clip_start_x or clip_stop_x < le.start_x:
                continue
            cr.rectangle(le.start_x, self.le_start_y, le.width, 10)
        cr.fill()

        # The marker for the tagged entries
        cr.set_source_rgb(1, 0.64, 0)
        for te in self.visible_tagged_entries:
            if te.stop_x < clip_start_x or clip_stop_x < te.start_x:
                continue
            cr.rectangle(te.start_x, self.te_end_y - 10, te.width, 10)
        cr.fill()

        if self.current_tagged_entry is not None:
            start_x = self.timeline_helper.datetime_to_pixel(
                self.current_tagged_entry.start)
            stop_x = self.timeline_helper.datetime_to_pixel(
                self.current_tagged_entry.stop)
            cr.set_source_rgba(0.2, 0.2, 0.2, 0.4)
            cr.rectangle(start_x, 0, stop_x - start_x, drawing_area_height)
            cr.fill()

        # Draw the sides
        cr.set_source_rgba(0.5, 0.5, 0.5, 0.5)
        cr.rectangle(0, 0, self.timeline_side_padding, drawing_area_height)
        cr.fill()
        cr.rectangle(canvas_width - self.timeline_side_padding, 0,
                     canvas_width, drawing_area_height)
        cr.fill()