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()
def __init__(self, source: BLImage) -> None: if source is None: raise ValueError("Argument 'source' is required.") super().__init__() (width, height) = source.size self._size = Dimension(width, height) self._source = source pixels = source.pixels[:] channels = 4 length = width * height def load_image() -> Iterable[int]: for i in range(0, length): offset = i * channels r = pixels[offset] g = pixels[offset + 1] b = pixels[offset + 2] a = pixels[offset + 3] yield int(b * 255) yield int(g * 255) yield int(r * 255) yield int(a * 255) data = bytearray(load_image()) pattern = ImageSurface.create_for_data(data, FORMAT_ARGB32, width, height) self._surface = ImageSurface(FORMAT_ARGB32, width, height) ctx = Graphics(self._surface) m = Matrix() m.translate(0, height) m.scale(1, -1) ctx.set_matrix(m) ctx.set_source_surface(pattern) ctx.paint() self.surface.flush() pattern.finish()
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(self, context: cairo.Context, x: float, y: float, fxy: FixXY): super().draw(context, x, y, fxy) context.set_source_surface(self.surf, *fxy(x + self.indent, y)) context.paint() self.surf.finish()
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 ()
for variant_name, variant_info in board_info["variants"].items(): if variant_name.startswith("_"): # skip "_base" continue # create canvas w_p = int(w * (1 + 2 * pad_sides)) canvas = ImageSurface(bg.get_format(), w_p, h) ctx = Context(canvas) ctx.set_source_rgb(1, 1, 1) ctx.rectangle(0, 0, w_p, h) ctx.fill() ctx.set_source_surface(bg, (w_p - w) // 2, -h_bg * y_offset) ctx.rectangle((w_p - w) // 2, 0, w, h_bg) ctx.fill() # make B&W ctx.set_source_rgb(0.5, 0.5, 0.5) ctx.set_operator(OPERATOR_HSL_SATURATION) ctx.rectangle(0, 0, w_p, h) ctx.fill() if True: canvas.write_to_png(f"{board_name}_bg.png") canvas = None from PIL import Image