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()
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 paint_foreground(self, ctx: Context): if self.border_corner: draw_rounded_rectangle(ctx, Rectangle(ZERO_TOP_LEFT, self.size), self.border_corner) ctx.clip() self.paint_scale_background(ctx) if self.values: pos = 0.0 for value in self.values: l_pos = pos pos += value[0] / self._total if value[1]: ctx.set_source_rgba(*value[1]) if self.orientation == BarWidget.Orientation.HORIZONTAL_LEFT_TO_RIGHT: ctx.rectangle(l_pos * self.width, 0, (pos - l_pos) * self.width, self.height) elif self.orientation == BarWidget.Orientation.HORIZONTAL_RIGHT_TO_LEFT: ctx.rectangle(self.width - l_pos * self.width, 0, self.width - (l_pos - pos) * self.width, self.height) elif self.orientation == BarWidget.Orientation.VERTICAL_DOWN: ctx.rectangle(0, l_pos * self.height, self.width, (pos - l_pos) * self.height) elif self.orientation == BarWidget.Orientation.VERTICAL_UP: ctx.rectangle(0, self.height - l_pos * self.height, self.width, (l_pos - pos) * self.height) ctx.fill() self.paint_scale_foreground(ctx) if self.border: ctx.set_source_rgba(*self.border) ctx.set_line_width(self.border_width) draw_rounded_rectangle(ctx, Rectangle(ZERO_TOP_LEFT, self.size), self.border_corner) ctx.stroke()
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()
def draw(self, ctx: Context, polygon: bool) -> None: line_width_current = self.line_width_initial ctx.set_source_rgb(self.color[0], self.color[1], self.color[2]) x_start = self.position[0] x_end = x_start + self.target_width y = self.position[1] while ((self.line_width_check_is_greater and line_width_current > self.line_width_final) or (not self.line_width_check_is_greater and line_width_current < self.line_width_final)): ctx.set_line_width(line_width_current) y += line_width_current / 2 if polygon: ctx.move_to(x_start, y - line_width_current / 2) ctx.line_to(x_end, y - line_width_current / 2) ctx.line_to(x_end, y + line_width_current / 2) ctx.line_to(x_start, y + line_width_current / 2) ctx.fill() else: ctx.move_to(x_start, y) ctx.line_to(x_end, y) ctx.stroke() # Add the white space y += line_width_current # prepare next line width y += line_width_current / 2 line_width_current += self.line_width_delta
def export_svg(fn, paths, size, line_with=0.1, scale_factor=None): from cairocffi 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()
def coloured_bezier(ctx: cairo.Context, p0, p1, p2, p3, colors, width, detail=100, fade=None): p0 = np.array(p0) p1 = np.array(p1) p2 = np.array(p2) p3 = np.array(p3) bez, bezd = cubic_bezier(p0, p1, p2, p3, numpoints=detail) bezd = normalize(bezd, norm='l2', axis=1) frac_sum = -.5 for color, frac in colors: (r, g, b, a) = color if fade is None: ctx.set_source_rgba(r, g, b, a) else: ctx.set_source(fade_pattern(p0[0], p0[1], p3[0], p3[1], r, g, b, a, fade)) ctx.set_line_width(frac*width) frac_sum += frac/2 ctx.move_to(bez[0][0] - width * frac_sum * bezd[0][1], bez[0][1] + width * frac_sum * bezd[0][0]) for i in range(0, bez.shape[0] - 3, 3): ctx.curve_to(bez[i + 1][0] - width * frac_sum * bezd[i + 1][1], bez[i + 1][1] + width * frac_sum * bezd[i + 1][0], bez[i + 2][0] - width * frac_sum * bezd[i + 2][1], bez[i + 2][1] + width * frac_sum * bezd[i + 2][0], bez[i + 3][0] - width * frac_sum * bezd[i + 3][1], bez[i + 3][1] + width * frac_sum * bezd[i + 3][0]) # for i in range(0, bez.shape[0] - 3, 2): # ctx.move_to(bez[i][0] - width * frac_sum * bezd[i][1], bez[i][1] + width * frac_sum * bezd[i][0]) # ctx.curve_to(bez[i + 1][0] - width * frac_sum * bezd[i + 1][1], bez[i + 1][1] + width * frac_sum * bezd[i + 1][0], # bez[i + 2][0] - width * frac_sum * bezd[i + 2][1], bez[i + 2][1] + width * frac_sum * bezd[i + 2][0], # bez[i + 3][0] - width * frac_sum * bezd[i + 3][1], bez[i + 3][1] + width * frac_sum * bezd[i + 3][0]) ctx.stroke() frac_sum += frac/2
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()
def draw(self, context: cairo.Context, x: float, y: float, fxy: FixXY): if debug: context.set_source_rgb(1 if self.no_page_break else 0, 0, 0) context.rectangle(*fxy(x - 5, y), *fxy(2, 16)) context.fill() context.set_source_rgb(0.5, 0.5, 0.5) context.rectangle(*fxy(self.indent + x, y), *fxy(self.width, self.height)) context.stroke()
def paint_foreground(self, ctx: Context): ctx.set_line_width(self.line_width) if self.orientation == Line.Orientation.HORIZONTAL: ctx.move_to(*self.size.position(Anchor.CENTER_LEFT)) ctx.line_to(*self.size.position(Anchor.CENTER_RIGHT)) else: ctx.move_to(*self.size.position(Anchor.TOP_CENTER)) ctx.line_to(*self.size.position(Anchor.BOTTOM_CENTER)) ctx.stroke()
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()
def draw_ray_trace(r0: Sequence[float], elements: Sequence[Element], ctx: cairo.Context, scale: float): ctx.save() r = r0 for element in elements: ctx.move_to(0, r[0] * scale) ctx.translate(element.thickness * scale, 0) rp = element.matrix.dot(r) ctx.line_to(0, rp[0] * scale) ctx.stroke() r = rp ctx.restore()
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
def paint_foreground(self, ctx: Context): if self._image: sx = self.width / self._image.get_width() sy = self.height / self._image.get_height() s = min(sx, sy) sw = self._image.get_width() * s sh = self._image.get_height() * s ctx.scale(s, s) x = 0 y = 0 if self.alignment == Anchor.TOP_LEFT: x = 0 y = 0 elif self.alignment == Anchor.TOP_CENTER: x = (self.width - sw) / 2 y = 0 elif self.alignment == Anchor.TOP_RIGHT: x = self.width - sw y = 0 elif self.alignment == Anchor.CENTER_LEFT: x = 0 y = (self.height - sh) / 2 elif self.alignment == Anchor.CENTER_CENTER: x = (self.width - sw) / 2 y = (self.height - sh) / 2 elif self.alignment == Anchor.CENTER_RIGHT: x = (self.width - sw) y = (self.height - sh) / 2 elif self.alignment == Anchor.BOTTOM_LEFT: x = 0 y = self.height - sh elif self.alignment == Anchor.BOTTOM_CENTER: x = (self.width - sw) / 2 y = self.height - sh elif self.alignment == Anchor.BOTTOM_RIGHT: x = self.width - sw y = self.height - sh x /= s y /= s ctx.set_source_surface(self._image, x, y) ctx.paint() else: ctx.move_to(0, 0) ctx.line_to(self.size.width, self.size.height) ctx.stroke() ctx.move_to(0, self.size.height) ctx.line_to(self.size.width, 0) ctx.stroke()
def draw_border( self, g: Graphics, component: T, color: RGBA, thickness: float = GlassLookAndFeel.BorderThickness) -> 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) g.set_line_width(thickness) self.draw_rect(g, area, 8) g.stroke()
def label_train_spaces(ctx: cairo.Context, train: trains.Train, radius_factors=1, broken_spaces: Sequence = None): """Draw material name and thickness of the spaces. Args: radius_factors (scalar or sequence): Factor by which the average interface radii is multiplied to place the text. If a scalar is given it is broadcast. """ spaces, brokens = break_spaces(train.spaces, broken_spaces) radius_factors = np.broadcast_to(radius_factors, (len(spaces), )) radius_last = train.interfaces[0].radius y_last = 0 h_last = 0 n = train.interfaces[0].n1 for space, next_interface, radius_factor in zip( spaces, train.interfaces + (None, ), radius_factors): if next_interface is None: radius_next = radius_last h_next = 0 else: radius_next = next_interface.radius h_next = functions.calc_sphere_sag(next_interface.roc, radius_next) y_next = y_last + space if space != 0: string = '%.3f mm %s' % (space * 1e3, n.name) radius = (radius_last + radius_next) / 2 x = radius_factor * radius y = (y_next + h_next + y_last + h_last) / 2 ctx.save() ctx.translate(x, y) ctx.show_text(string) ctx.new_path() ctx.restore() if radius_factor > 1: draw_polyline(ctx, ((radius, y), (x, y))) ctx.stroke() y_last = y_next h_last = h_next if next_interface is not None: n = next_interface.n2 radius_last = next_interface.radius
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
def label_interface(ctx: cairo.Context, face: trains.Interface, radius_factor=1): """Draw text saying ROC, and a line from the edge of the interface to the text. Args: radius_factor (scalar): Factor by which interface radius is multiplied to get text x position. """ x = radius_factor * face.radius y = functions.calc_sphere_sag(face.roc, face.radius) string = 'ROC %.3f mm' % (face.roc * 1e3) ctx.set_source_rgb(0, 0, 0) ctx.save() ctx.translate(x, y) ctx.show_text(string) ctx.new_path() ctx.restore() if radius_factor > 1: draw_polyline(ctx, ((face.radius, y), (x, y))) ctx.stroke()
def draw_labels(self, ctx: Context) -> None: point_diameter_current = self.point_diameter_initial text_height_room = 0 ctx.set_source_rgb(self.color[0], self.color[1], self.color[2]) points_per_row = math.floor(self.target_width / self.point_margin) i = 0 while ((self.point_diameter_check_is_greater and point_diameter_current > self.point_diameter_final) or (not self.point_diameter_check_is_greater and point_diameter_current < self.point_diameter_final)): col = i % points_per_row row = math.floor(i / points_per_row) x = self.position[ 0] + col * self.point_margin + self.point_margin / 2 y = self.position[ 1] + row * self.point_margin + self.point_margin / 2 first_point_diameter_in_row = point_diameter_current last_point_diameter_in_row = point_diameter_current + self.point_diameter_delta * ( points_per_row - 1) print(first_point_diameter_in_row) print(last_point_diameter_in_row) if text_height_room > 2: ctx.move_to(x + 0, y) ctx.line_to(x + 2, y) ctx.stroke() self.draw_text( ctx, "{0:.3f} - {1:.3f}".format(first_point_diameter_in_row, last_point_diameter_in_row) + " mm", x + 3, y, 2) text_height_room = 0 i += points_per_row point_diameter_current += self.point_diameter_delta * points_per_row text_height_room += self.point_margin
def _show_layout_baseline( context: cairocffi.Context, layout: pangocffi.Layout ): layout_iter = layout.get_iter() context.set_line_width(0.5) context.set_dash([1, 1]) while True: extents = layout_iter.get_line_extents() baseline = layout_iter.get_baseline() y_ranges = layout_iter.get_line_yrange() context.set_source_rgba(1, 0, 0, 0.9) context.move_to( pangocffi.units_to_double(extents[0].x), pangocffi.units_to_double(y_ranges[0]) ) context.line_to( pangocffi.units_to_double(extents[0].x + extents[0].width), pangocffi.units_to_double(y_ranges[0]) ) context.stroke() context.set_source_rgba(0, 1, 0, 0.9) context.stroke() context.move_to( pangocffi.units_to_double(extents[0].x), pangocffi.units_to_double(baseline) ) context.line_to( pangocffi.units_to_double(extents[0].x + extents[0].width), pangocffi.units_to_double(baseline) ) context.stroke() context.set_source_rgba(0, 0, 1, 0.9) context.move_to( pangocffi.units_to_double(extents[0].x), pangocffi.units_to_double(y_ranges[1]) ) context.line_to( pangocffi.units_to_double(extents[0].x + extents[0].width), pangocffi.units_to_double(y_ranges[1]) ) context.stroke() if not layout_iter.next_run(): break
def _generate_layer(self, transcription, page, layer): surface = PDFSurface(layer, *page.page_size) context = Context(surface) # context.select_font_face('Georgia') context.set_source_rgba(1, 1, 1, 1 / 256) # almost invisible context.set_font_size(2) for line_ink, line_transcription in zip(page.lines, transcription): ink, transformation = writing.normalized(line_ink) context.save() context.transform( Matrix(*(Transformation.translation( 0, page.page_size[1]).parameter))) context.transform(Matrix(*(Transformation.mirror(0).parameter))) context.transform(Matrix(*((~transformation).parameter))) context.transform(Matrix(*(Transformation.mirror(0).parameter))) HANDWRITING_WIDTH = ink.boundary_box[1] TYPEWRITING_WIDTH = context.text_extents(line_transcription)[2] context.scale(HANDWRITING_WIDTH / TYPEWRITING_WIDTH, 1) context.move_to(0, 0) context.show_text(line_transcription) context.restore() context.stroke() context.show_page() surface.flush()
def draw_labels(self, ctx: Context): ctx.set_line_width(0.1) line_width_current = self.line_width_initial text_height_room = 0 ctx.set_source_rgb(self.color[0], self.color[1], self.color[2]) x = self.position[0] y = self.position[1] while ((self.line_width_check_is_greater and line_width_current > self.line_width_final) or (not self.line_width_check_is_greater and line_width_current < self.line_width_final)): y += line_width_current / 2 text_height_room += line_width_current / 2 # Draw the line annotating the row if text_height_room > 2: ctx.move_to(x + 0, y) ctx.line_to(x + 2, y) ctx.stroke() self.draw_text(ctx, "{0:.2f}".format(line_width_current) + " mm", x + 3, y, 2) text_height_room = 0 # Add the white space y += line_width_current text_height_room += line_width_current # prepare next line width y += line_width_current / 2 text_height_room += line_width_current / 2 line_width_current += self.line_width_delta
def _show_layout_y_ranges( 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() y_ranges = layout_iter.get_line_yrange() context.set_source_rgba(0, 0, 1 if alternate else 0.5, 0.9) context.move_to( pangocffi.units_to_double(extents[0].x), pangocffi.units_to_double(y_ranges[0]) ) context.line_to( pangocffi.units_to_double(extents[0].x + extents[0].width), pangocffi.units_to_double(y_ranges[0]) ) context.stroke() context.move_to( pangocffi.units_to_double(extents[0].x), pangocffi.units_to_double(y_ranges[1]) ) context.line_to( pangocffi.units_to_double(extents[0].x + extents[0].width), pangocffi.units_to_double(y_ranges[1]) ) context.stroke() if not layout_iter.next_run(): break
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 ()
def _draw_water(self, ctx: Context, outline: Union[Polygon, MultiPolygon]): # Draw outline of ripple CairoHelper.draw_polygon(ctx, outline) ctx.stroke() self._draw_ripples(ctx, outline)
def _(d: Arc, ctx: cairo.Context, scale: float): ctx.save() ctx.arc(d.xc * scale, d.yc * scale, d.radius * scale, d.theta0, d.theta1) ctx.stroke() ctx.restore()
y = mean_pin_y - label_height // 2 print(f"{text=}\t{y=}") if pass_ == 0: ctx.set_source_rgba(*color, 1) draw_rounded_rectangle(ctx, x, y, label_width, label_height, label_radius) ctx.fill() for pin_name in pin_names: pin_x, pin_y, align = pin_defs[pin_name] pin_x = pin_x * w pin_y = pin_y * h_bg - h_bg * y_offset ctx.move_to(line_origin_x, y + label_height // 2) ctx.line_to(w * pad_sides + pin_x, pin_y) ctx.set_line_width(4) ctx.stroke() else: ctx.move_to(x + label_pad[0] - x_bearing, y - y_bearing + label_pad[1]) ctx.set_source_rgb(1, 1, 1) ctx.show_text(text) # save to file canvas.write_to_png(f"{board_name}_{variant_name}.png") # stride = ImageSurface.format_stride_for_width(format, width) # data = bytearray(stride * height) # surface = ImageSurface(format, width, height, data, stride)
def _draw_wall(self, ctx: Context, line_string: LineString): CairoHelper.draw_line_string(ctx, line_string) ctx.stroke()
def make_interface(ctx: cairo.Context, face: trains.Interface, num_points=32): draw_polyline(ctx, face.get_points(num_points)) ctx.stroke()
def _draw_ripple(self, ctx: Context, ripple: Polygon, iteration: int): CairoHelper.draw_polygon(ctx, ripple) ctx.stroke()