def draw_keylayer(self, canvas, rect, typeface): canvas.save() if self.keylayer == Keylayer.Cmd: canvas.drawRect( skia.Rect.MakeXYWH(0, rect.h - 50, rect.w, 50), skia.Paint(AntiAlias=True, Color=hsl(0.9, l=0.25, a=0.85).skia())) canvas.drawString( "".join(self.keybuffer), 10, rect.h - 14, skia.Font(typeface, 30), skia.Paint(AntiAlias=True, Color=skia.ColorWHITE)) elif self.keylayer == Keylayer.Text: canvas.drawRect( skia.Rect.MakeXYWH(0, 0, rect.w, 50), skia.Paint(AntiAlias=True, Color=hsl(0.7, l=0.25, a=0.85).skia())) canvas.drawString( "".join(self.keybuffer), 10, 34, skia.Font(typeface, 30), skia.Paint(AntiAlias=True, Color=skia.ColorWHITE)) elif self.keylayer == Keylayer.Editing: canvas.drawRect( skia.Rect(0, 0, 50, 50), skia.Paint(AntiAlias=True, Color=hsl(0.95, l=0.5, a=0.75).skia())) canvas.restore()
class Renderer(object): GREEN = skia.Paint(Color=skia.ColorGREEN) TEXT_COLOR = skia.Paint(Color=skia.ColorWHITE) def __init__(self, window): self.window = window self.context = skia.GrDirectContext.MakeGL() self.width, self.height = glfw.get_window_size(window) backend_render_target = skia.GrBackendRenderTarget( self.width, self.height, 0, # sampleCnt 0, # stencilBits skia.GrGLFramebufferInfo(0, GL.GL_RGBA8)) self.surface = skia.Surface.MakeFromBackendRenderTarget( self.context, backend_render_target, skia.kBottomLeft_GrSurfaceOrigin, skia.kRGBA_8888_ColorType, skia.ColorSpace.MakeSRGB()) # typeface = skia.Typeface.MakeFromFile('JetBrainsMono-Regular.ttf') self.font = skia.Font(skia.Typeface.MakeDefault(), size=40) print(self.font) self.text = skia.TextBlob.MakeFromString('drawTextBlob', self.font) self.start = time.time() assert self.surface is not None def __del__(self): self.context.abandonContext() def render(self): t = time.time() - self.start with self.surface as canvas: canvas.drawCircle(self.width/2 + 100 * math.cos(t), self.height/2 + 100 * math.sin(t), 40, self.GREEN) canvas.drawString('drawString', x=100, y=100, font=self.font, paint=self.TEXT_COLOR) canvas.drawTextBlob(self.text, x=100, y=200, paint=self.TEXT_COLOR) self.surface.flushAndSubmit()
def draw_line(self, canvas, structure, x_values, y_values, style): ## Cache colors if not style.cached_renderer: style.cache_renderer(self) elif style.cached_renderer != self: style.cache_renderer(self) ## Create a path path = skia.Path() ## Load points into path pointer = 0 for p_count in structure: path.moveTo(x_values[pointer], y_values[pointer]) for index in range(pointer, pointer + p_count): path.lineTo(x_values[index], y_values[index]) pointer += p_count ## Create outline paint paint = skia.Paint(style._outline_color_cache) paint.setStyle(skia.Paint.kStroke_Style) paint.setStrokeWidth(style.weight + style.outline_weight) paint.setAntiAlias(True) ## Draw outline path canvas.drawPath(path, paint) ## Create line paint paint = skia.Paint(style._color_cache) paint.setStyle(skia.Paint.kStroke_Style) paint.setStrokeWidth(style.weight) paint.setAntiAlias(True) ## Draw line path canvas.drawPath(path, paint)
def draw_point(self, canvas, structure, x_values, y_values, style): ## Cache colors if not style.cached_renderer: style.cache_renderer(self) elif style.cached_renderer != self: style.cache_renderer(self) ## Create a path path = skia.Path() ## Add points to path pointer = 0 for p_count in structure: for index in range(pointer, pointer + p_count): path.addCircle(x_values[index], y_values[index], style.weight) pointer += p_count ## Draw background paint = skia.Paint(AntiAlias=True) paint.setColor(style._color_cache) canvas.drawPath(path, paint) ## Draw outline paint.setStyle(skia.Paint.kStroke_Style) paint.setColor(style._outline_color_cache) paint.setStrokeWidth(style.outline_weight) canvas.drawPath(path, paint)
def anchored_text(self, canvas, text, x: int, y: int, anchor_x: float, anchor_y: float, **kwargs): # If user sent a single string, it means a 1 item list if not isinstance(text, list): text = [text] # Get paint, font paint = kwargs.get("paint", skia.Paint(AntiAlias=True, Color=skia.ColorWHITE)) font = kwargs.get("font", skia.Font(skia.Typeface('Arial'), 24)) # Width and height of text height_size = font.getSpacing() for line_number, text_string in enumerate(text): text_size = font.measureText(text_string) # Where we'll plot the top left text according to the anchor and whatnot real_x = x - (text_size * anchor_x) real_y = y - (height_size * anchor_y) + height_size + (line_number * height_size) canvas.drawString(text_string, real_x, real_y, font, paint)
def blit(self) -> None: # Vectorial objects blit themselves on a .next() function if self.is_vectorial: return # Invert x and y because top left is (0, 0), y first y = int(self.x + self.offset[1]) x = int(self.y + self.offset[0]) if self.mask_filters: self.paint_dict["MaskFilter"] = self.mask_filters if self.image_filters: self.paint_dict["ImageFilter"] = skia.ImageFilters.Merge( self.image_filters) # Get a paint with the options, image filters (if any) for skia to draw paint = skia.Paint(self.paint_dict) # Blit this image self.mmvskia_main.skia.canvas.drawImage( self.image.image, x, y, paint=paint, )
def draw(self): for i in self.items: if 'fill' in i.style: paint = skia.Paint() paint.setStyle(skia.Paint.kFill_Style) paint.setAntiAlias(True) paint.setColor(i.style['fill']) self.canvas.drawPath(i.draw(), paint) if 'stroke' in i.style: paint = skia.Paint() paint.setStyle(skia.Paint.kStroke_Style) paint.setStrokeWidth(i.style['stroke_width']) paint.setColor(i.style['stroke']) paint.setAntiAlias(True) self.canvas.drawPath(i.draw(), paint) self.drawn = True
def draw_markers(self): # The paint of markers in between white keys white_white_paint = skia.Paint( AntiAlias = True, Color = self.colors["marker_color_between_two_white"], Style = skia.Paint.kStroke_Style, StrokeWidth = 1, ) current_center = 0 # Check if prev and this key is white, keeps track of a current_center, create rect to draw and draw for index, key_index in enumerate(self.piano_keys.keys()): key = self.piano_keys[key_index] if not index == 0: prevkey = self.piano_keys[key_index - 1] if (prevkey.is_white) and (key.is_white): current_center += self.tone_width rect = skia.Rect( current_center - self.semitone_width, 0, current_center - self.semitone_width, self.mmvskia_main.context.height ) self.mmvskia_main.skia.canvas.drawRect(rect, white_white_paint) else: current_center += self.semitone_width # Ask each key to draw their CENTERED marker for key_index in self.piano_keys.keys(): self.piano_keys[key_index].draw_marker()
def draw_marker(self): # If the note is a G, it's a mid way reference on the piano # This considers G# keys only if "G" in self.name and self.is_black: color = self.colors["marker_color_g_sharp"] elif self.is_black: color = self.colors["marker_color_sharp_keys"] else: return if color is None: return # The marker paint marker = skia.Paint( AntiAlias = True, Color = color, Style = skia.Paint.kFill_Style, # StrokeWidth = 2, ) # Draw through the entire vertical space of the screen rect = skia.Rect( max(self.center_x - (self.width / 10), 1), 0, max(self.center_x + (self.width / 10), 1), self.resolution_height - self.height ) self.mmvskia_main.skia.canvas.drawRect(rect, marker)
def draw_markers(self): c = 0.35 white_white_color = skia.Color4f(c, c, c, 1) white_white_paint = skia.Paint( AntiAlias=True, Color=white_white_color, Style=skia.Paint.kStroke_Style, StrokeWidth=1, ) current_center = 0 for index, key_index in enumerate(self.piano_keys.keys()): key = self.piano_keys[key_index] if not index == 0: prevkey = self.piano_keys[key_index - 1] if (prevkey.is_white) and (key.is_white): current_center += self.tone_width rect = skia.Rect(current_center - self.semitone_width, 0, current_center + 1 - self.semitone_width, self.vectorial.context.height) self.skia.canvas.drawRect(rect, white_white_paint) else: current_center += self.semitone_width for key_index in self.piano_keys.keys(): self.piano_keys[key_index].draw_marker()
def draw_text(self, canvas, text_line, x_pos, y_pos, text_style=None): """ """ ## Create a list to hold Typeface constructor args typeface_args = [text_line.font] ## Append FontStyle objects to list depending on params if text_line.italic and text_line.bold: typeface_args.append(skia.FontStyle.BoldItalic()) elif text_line.bold: typeface_args.append(skia.FontStyle.Bold()) elif text_line.italic: typeface_args.append(skia.FontStyle.Italic()) ## Create FontStyle object from constructor args typeface = skia.Typeface(*typeface_args) ## Create a font and set params font = skia.Font() font.setSize(float(text_line.size)) font.setTypeface(typeface) ## Create a paint object paint = skia.Paint(self.cache_color(text_line.color)) if text_style: width = font.measureText(text_line.text) height = font.getSize() * 1.334 #! I really hate this hack x_pos -= width / 2 y_pos += height / 2 ## Draw Text Line! canvas.drawSimpleText(text_line.text, x_pos, y_pos, font, paint)
def _makePaint(self, style): paint = skia.Paint( Color=0, AntiAlias=True, Style=style, ) paint.setARGB(*self.color) paint.setBlendMode(_blendModeMapping[self.blendMode]) return paint
def _paint(x, fill=True, thickness=0) -> skia.Paint: style = skia.Paint.kStrokeAndFill_Style if fill else skia.Paint.kStroke_Style color = Color._from_whatever(x) cache_key = (color, fill, thickness) if cache_key not in Color._cache: p = skia.Paint(AntiAlias=True, StrokeWidth=thickness, Color=color, Style=style) Color._cache[cache_key] = p return p return Color._cache[cache_key]
def drawBackgroundHighlighted(self, canvas, odd, rect): paint = skia.Paint() paint.setStyle(skia.Paint.kFill_Style) paint.setAntiAlias(True) paint.setColor(self.highlight_bg_color) canvas.drawRect(rect, paint) #Sidebar paint.setColor(self.highlight_sidebar_color) canvas.drawRect(skia.Rect(0, 0, 5, rect.height()), paint)
def drawBackground(self, canvas, odd, rect): paint = skia.Paint() paint.setStyle(skia.Paint.kFill_Style) paint.setAntiAlias(True) if odd: paint.setColor(self.odd_bg) else: paint.setColor(self.even_bg) canvas.drawRect(rect, paint)
def draw(self, notes_playing): if self.is_black: away = (self.height * (0.33)) else: away = 0 coords = [ self.center_x - (self.width / 2), self.resolution_height - self.height, self.center_x + (self.width / 2), self.resolution_height - away, ] self.active = self.note in notes_playing if self.active: color = self.color_active else: color = self.color_idle # Make the skia Paint and paint = skia.Paint( AntiAlias=True, Color=color, Style=skia.Paint.kFill_Style, StrokeWidth=2, ) border = skia.Paint( AntiAlias=True, Color=skia.Color4f(0, 0, 0, 1), Style=skia.Paint.kStroke_Style, StrokeWidth=2, ) # Rectangle border rect = skia.Rect(*coords) # Draw the border self.skia.canvas.drawRect(rect, paint) self.skia.canvas.drawRect(rect, border)
def _makePaint(self): paint = skia.Paint( Color=0, AntiAlias=True, Style=self._skPaintStyle, ) paint.setARGB(*self.color) paint.setBlendMode(_blendModeMapping[self.blendMode]) if self.shader is not None: paint.setShader(self.shader) return paint
def draw(self, notes_playing): # If the note is black we leave a not filled spot on the bottom, this is the ratio of it away = (self.height * (0.33)) if self.is_black else 0 # Based on the away, center, width, height etc, get the coords of this piano key coords = [ self.center_x - (self.width / 2), self.resolution_height - self.height, self.center_x + (self.width / 2), self.resolution_height - away, ] # Is the note active self.active = self.note in notes_playing # Get the color based on if the note is active or not color = self.color_active if self.active else self.color_idle # Make the skia Paint and key_paint = skia.Paint( AntiAlias=True, Color=color, Style=skia.Paint.kFill_Style, StrokeWidth=2, ) # The border of the key key_border = skia.Paint( AntiAlias=True, Color=skia.Color4f(0, 0, 0, 1), Style=skia.Paint.kStroke_Style, StrokeWidth=2, ) # Rectangle border rect = skia.Rect(*coords) # Draw the border self.mmvskia_main.skia.canvas.drawRect(rect, key_paint) self.mmvskia_main.skia.canvas.drawRect(rect, key_border)
def image(self, imagePath, position, alpha=1.0): im = self._getImage(imagePath) paint = skia.Paint() if alpha != 1.0: paint.setAlpha(round(alpha * 255)) if self._gstate.fillPaint.blendMode != "normal": paint.setBlendMode(self._gstate.fillPaint.skPaint.getBlendMode()) x, y = position with self._savedCanvasState(): self._canvas.translate(x, y + im.height()) if self._flipCanvas: self._canvas.scale(1, -1) self._canvas.drawImage(im, 0, 0, paint)
def renderSnapshot(self, msg, canvas, ms, line): frame = msg.snapshot(ms) w = frame.width() h = frame.height() src = skia.Rect.MakeXYWH(0, 0, w, h) fW = w * msg.fade sW = (fW + w) sH = (line + h) dst = skia.Rect(fW, line, sW, sH) tempPaint = skia.Paint() tempPaint.setFilterQuality(skia.FilterQuality.kHigh_FilterQuality) canvas.drawImageRect(frame, src, dst, tempPaint)
def __init__(self, cachedTypefaces=None, _doInitialize=True): if cachedTypefaces is None: cachedTypefaces = {} self.doFill = True self.doStroke = False self._cachedTypefaces = cachedTypefaces if not _doInitialize: # self.copy() will initialize further return self.fillPaint = skia.Paint( Color=0xFF000000, AntiAlias=True, Style=skia.Paint.kFill_Style, ) self.strokePaint = skia.Paint( Color=0xFF000000, AntiAlias=True, Style=skia.Paint.kStroke_Style, ) self.strokePaint.setStrokeMiter(5) # default better matching DrawBot self.textStyle = TextStyle(cachedTypefaces)
def render_frame(self, ms): with skia_canvas(self.chatWidth, self.chatHeight) as canvas: paint = skia.Paint() paint.setStyle(skia.Paint.kFill_Style) paint.setColor(self.options['bg']) canvas.drawRect(self.frame_rect, paint) line = 0 for msg in self.current_frame_msgs: self.renderSnapshot(msg, canvas, ms, line) line += msg.lheight * self.lineHeight canvas.readPixels( skia.ImageInfo.MakeN32Premul(self.chatWidth, self.chatHeight), self.buffer)
def particles(self): print(f"Saving generated particle N=[", end="", flush=True) # Repeat for N images for i in range(self.n_images): # Reset canvas to transparent self.skia.reset_canvas() # How much nodes of gradients in this particle npoints = random.randint(1, 6) # Random scalars for each node, plus ending at zero scalars = [random.uniform(0.2, 1) for _ in range(npoints)] + [0] # Colors list colors = [] # Iterate in decreasing order for scalar in reversed(sorted(scalars)): colors.append(skia.Color4f(1, 1, 1, scalar)) # Create the skia paint with a circle at the center that ends on the edge paint = skia.Paint(Shader=skia.GradientShader.MakeRadial( center=(self.width / 2, self.height / 2), radius=self.width / 2, colors=colors, )) # Draw the particles self.canvas.drawPaint(paint) # # Save the image # Get the PIL image from the array of the canvas img = Image.fromarray(self.skia.canvas_array()) # Pretty print if not i == self.n_images - 1: print(f"{i}, ", end="", flush=True) else: print(f"{i}]") # Save the particle to the output dir img.save(self.output_dir + f"/particle-{i}.png", quality=100)
def drawScaledImage(self, image, scale, line, pos, canvas): w = image.width() h = image.height() of = round(line - (h * scale) / 2 - self.spacer / 4) #Destination nX = pos.x() nY = round(of + pos.y()) sW = round(nX + w * scale) sH = round(nY + h * scale) dst = skia.Rect(nX, nY, sW, sH) tempPaint = skia.Paint() tempPaint.setFilterQuality(skia.FilterQuality.kHigh_FilterQuality) tempPaint.setAntiAlias(False) canvas.drawImageRect(image, skia.Rect(0, 0, w, h), dst, tempPaint)
def draw_marker(self): if self.MARKER and self.is_black: if "G" in self.name: color = self.marker_color_subtle_brighter else: color = self.marker_color marker = skia.Paint( AntiAlias=True, Color=color, Style=skia.Paint.kFill_Style, # StrokeWidth = 2, ) rect = skia.Rect(max(self.center_x - (self.width / 10), 1), 0, max(self.center_x + (self.width / 10), 1), self.resolution_height - self.height) self.skia.canvas.drawRect(rect, marker)
def skPaintShadowAndOffset(self): if self.shadow is None: return None, None offset, blur, color = self.shadow color = _colorTupleToInt(_colorArgs(color)) if not blur: blur = 1 # MaskFilter.MakeBlur( # style: skia.BlurStyle, # sigma: float, # respectCTM: bool = True) → skia.MaskFilter blurMask = skia.MaskFilter.MakeBlur(skia.kNormal_BlurStyle, 0.5 * blur, False) paint = skia.Paint( Color=color, MaskFilter=blurMask, Style=self._skPaintStyle, ) return paint, offset
def draw(canvas): from math import cos, sin scale = 256. R = 0.45 * scale TAU = 6.2831853 path = skia.Path() path.moveTo(R, 0.) for i in range(7): theta = 3 * i * TAU / 7 path.lineTo(R * cos(theta), R * sin(theta)) path.close() paint = skia.Paint() paint.setAntiAlias(True) canvas.clear(0xFFFFFFFF) canvas.translate(0.5 * scale, 0.5 * scale) canvas.drawPath(path, paint)
def render_gui(): try: with skia_surface(window) as surface: with surface as canvas: canvas.clear(skia.Color(0, 0, 0)) scroll = db['gui_status'].get('scroll_x')['value'], db['gui_status'].get('scroll_y')['value'] canvas.translate(*scroll) for widget in db['widget'].rows: blob = skia.TextBlob.MakeFromString(widget['text'], font) canvas.save() canvas.drawRect(skia.Rect(widget['x'], widget['y'], widget['x']+widget['width'], widget['y']+widget['height']), skia.Paint(AntiAlias=True, Style=skia.Paint.kFill_Style, Color=skia.ColorBLUE)) canvas.clipRect(skia.Rect(widget['x'], widget['y'], widget['x']+widget['width'], widget['y']+widget['height'])) canvas.drawTextBlob(blob, widget['x'], widget['y']+widget['height'], skia.Paint(AntiAlias=True, Color=skia.Color(255, 255, 255))) canvas.restore() surface.flushAndSubmit() glfw.swap_buffers(window) except Exception as e: traceback.print_exc()
def __init__(self, dat, rect, canvas, scale, style=None, alpha=1): super().__init__(dat, rect.h) self.scale = scale self.canvas = canvas self.rect = rect self.blendmode = None self.style = style self.alpha = alpha all_attrs = list(self.findStyledAttrs(style)) skia_paint_kwargs = dict(AntiAlias=True) for attrs, attr in all_attrs: method, *args = attr if method == "skp": skia_paint_kwargs = args[0] if "AntiAlias" not in skia_paint_kwargs: skia_paint_kwargs["AntiAlias"] = True elif method == "blendmode": self.blendmode = args[0] for attrs, attr in all_attrs: self.paint = skia.Paint(**skia_paint_kwargs) if self.blendmode: self.paint.setBlendMode(self.blendmode) method, *args = attr if method == "skp": pass elif method == "skb": pass elif method == "blendmode": pass elif method == "stroke" and args[0].get("weight") == 0: pass else: canvas.save() did_draw = self.applyDATAttribute(attrs, attr) self.paint.setAlphaf(self.paint.getAlphaf() * self.alpha) if not did_draw: canvas.drawPath(self.path, self.paint) canvas.restore()
def main(): if not glfw.init(): return glfw.window_hint(glfw.STENCIL_BITS, 8) window = glfw.create_window(WIDTH, HEIGHT, 'Hello World', None, None) if not window: glfw.terminate() return glfw.make_context_current(window) context = skia.GrContext.MakeGL() backend_render_target = skia.GrBackendRenderTarget( WIDTH, HEIGHT, 0, # sampleCnt 0, # stencilBits skia.GrGLFramebufferInfo(0, gl.GL_RGBA8)) surface = skia.Surface.MakeFromBackendRenderTarget( context, backend_render_target, skia.kBottomLeft_GrSurfaceOrigin, skia.kRGBA_8888_ColorType, skia.ColorSpace.MakeSRGB()) assert surface is not None start = time.time() while (glfw.get_key(window, glfw.KEY_ESCAPE) != glfw.PRESS and not glfw.window_should_close(window)): t = time.time() - start gl.glClear(gl.GL_COLOR_BUFFER_BIT) with surface as canvas: canvas.drawCircle(100 + 10 * t, 100 + 10 * t, 40, skia.Paint(Color=skia.ColorGREEN)) surface.flushAndSubmit() glfw.swap_buffers(window) glfw.poll_events() context.abandonContext() glfw.terminate()