def fitToWidth(self): if self.msg.isHighlightedNotice(): offset = 10 #offset the messages so they are not at the edge else: offset = 5 x = offset # Measure timestamp if self.timestamped: self.msg.ftimestamp.cache(self.drawOptions) self.timestampPos = skia.Point(x, 0) nl = x + self.msg.ftimestamp.width x += nl + 3 # Measure badges self.badgePos = [] for bn in self.msg.badges: if not bn: continue #badges might be missing bn.cache(self.drawOptions, self.scale) self.badgePos.append(skia.Point(x, 0)) x += bn.width + 5 # Cache and Measure username self.msg.username.text += ": " self.msg.username.cache(self.drawOptions) self.usernamePos = skia.Point(x, 0) x += self.msg.username.width # Measure message content line = 1 self.contentPos = [] for n in self.msg.nodes: # Cache node n.cache(self.drawOptions, scale=self.scale) # what scale oX = 0 oY = 0 nl = n.width #This should be a nice solution to new line handling if x + nl > self.width or (hasattr(n, 'newline') and n.newline): line += 1 oX = offset x = nl else: oX = x + offset x += nl oY = (line - 1) * self.lh self.contentPos.append(skia.Point(oX, oY)) self.lheight = line
def renderNode(self, node, canvas, pos=skia.Point(0, 0), line=0, msec=0): if isinstance(node, TextNode): if node.stype == 'username': canvas.drawTextBlob(node.text_blob, pos.x(), line + pos.y(), self.drawOptions.usrPaint) elif node.stype == 'timestamp': canvas.drawTextBlob(node.text_blob, pos.x(), line + pos.y(), self.drawOptions.tstampPaint) else: canvas.drawTextBlob(node.text_blob, pos.x(), line + pos.y(), self.drawOptions.txtPaint) elif isinstance(node, LinkNode): canvas.drawTextBlob(node.text_blob, pos.x(), line + pos.y(), self.drawOptions.txtPaint) elif isinstance(node, MentionNode): canvas.drawTextBlob(node.text_blob, pos.x(), line + pos.y(), self.drawOptions.txtPaint) elif isinstance(node, CheermoteNode): node.image.seek(msec) frame = node.image.getFrame() self.drawOptions.drawScaledImage(frame, self.scale, line, pos, canvas) elif isinstance(node, BadgeNode): node.image.seek(msec) frame = node.image.getFrame() self.drawOptions.drawScaledImage(frame, self.scale, line, pos, canvas) elif isinstance(node, EmoteNode): node.image.seek(msec) frame = node.image.getFrame() self.drawOptions.drawScaledImage(frame, self.scale, line, pos, canvas)
def __get_graphics_path(element): #================================ if element.tag == SVG_NS('path'): tokens = list(parse_svg_path(element.attrib.get('d', ''))) path = SVGTiler.__path_from_tokens(tokens) elif element.tag == SVG_NS('rect'): (width, height) = (length_as_pixels(element.attrib.get('width', 0)), length_as_pixels(element.attrib.get('height', 0))) if width == 0 or height == 0: return None (rx, ry) = (length_as_pixels(element.attrib.get('rx', 0)), length_as_pixels(element.attrib.get('ry', 0))) if rx is None and ry is None: rx = ry = 0 elif ry is None: ry = rx elif rx is None: rx = ry rx = min(rx, width/2) ry = min(ry, height/2) (x, y) = (length_as_pixels(element.attrib.get('x', 0)), length_as_pixels(element.attrib.get('y', 0))) if rx == 0 and ry == 0: path = skia.Path.Rect((x, y, width, height)) else: path = skia.Path.RRect((x, y, width, height), rx, ry) elif element.tag == SVG_NS('line'): x1 = length_as_pixels(element.attrib.get('x1', 0)) y1 = length_as_pixels(element.attrib.get('y1', 0)) x2 = length_as_pixels(element.attrib.get('x2', 0)) y2 = length_as_pixels(element.attrib.get('y2', 0)) path = SVGTiler.__path_from_tokens(['M', x1, y1, x2, y2]) elif element.tag == SVG_NS('polyline'): points = element.attrib.get('points', '').replace(',', ' ').split() path = SVGTiler.__path_from_tokens(['M'] + points) elif element.tag == SVG_NS('polygon'): points = [ float(p) for p in element.attrib.get('points', '').replace(',', ' ').split() ] skia_points = [skia.Point(*points[n:n+2]) for n in range(0, len(points), 2)] path = skia.Path.Polygon(skia_points, True) elif element.tag == SVG_NS('circle'): r = length_as_pixels(element.attrib.get('r', 0)) if r == 0: return None (cx, cy) = (length_as_pixels(element.attrib.get('cx', 0)), length_as_pixels(element.attrib.get('cy', 0))) path = skia.Path.Circle(cx, cy, r) elif element.tag == SVG_NS('ellipse'): (rx, ry) = (length_as_pixels(element.attrib.get('rx', 0)), length_as_pixels(element.attrib.get('ry', 0))) if rx == 0 or ry == 0: return None (cx, cy) = (length_as_pixels(element.attrib.get('cx', 0)), length_as_pixels(element.attrib.get('cy', 0))) path = skia.Path.Oval((cx-rx, cy-ry, cx+rx, cy+ry)) return path
def vertices(): return skia.Vertices( skia.Vertices.kTriangles_VertexMode, [skia.Point(0, 0), skia.Point(1, 1), skia.Point(1, 0)], [skia.Point(1, 1), skia.Point(1, 0), skia.Point(0, 0)], [skia.ColorRED, skia.ColorRED, skia.ColorRED], )
def test_conic(path): pt = skia.Point(100, 0) path.moveTo(0, 0) path.conicTo(pt, pt, 1) meas = skia.PathMeasure(path, False) (stdP, tan) = postan(meas, 20) path.reset() path.moveTo(0, 0) path.conicTo(pt, pt, 10) meas.setPath(path, False) (hiP, tan) = postan(meas, 20) assert 19.5 < stdP.x() and stdP.x() < 20.5 assert 19.5 < hiP.x() and hiP.x() < 20.5
def test_Path_IsCubicDegenerate(path): assert isinstance( skia.Path.IsCubicDegenerate(skia.Point(0, 0), skia.Point(1, 1), skia.Point(1, 0.5), skia.Point(1, 0), False), bool)
def test_Path_addPoly(path): assert isinstance(path.addPoly([skia.Point(10, 10)], True), skia.Path)
def test_Path_conservativelyContainsRect(path): assert isinstance(path.conservativelyContainsRect(skia.Rect()), bool) def test_Path_incReserve(path): path.incReserve(0) def test_Path_shrinkToFit(path): path.shrinkToFit() @pytest.mark.parametrize('args', [ (0, 0), (skia.Point(0, 0), ), ]) def test_Path_moveTo(path, args): assert isinstance(path.moveTo(*args), skia.Path) def test_Path_rMoveTo(path): assert isinstance(path.rMoveTo(0, 0), skia.Path) @pytest.mark.parametrize('args', [ (1, 1), (skia.Point(1, 0), ), ]) def test_Path_lineTo(path, args): assert isinstance(path.lineTo(*args), skia.Path)
def test_GradientShader_MakeTwoPointConical(): assert isinstance(skia.GradientShader.MakeTwoPointConical( skia.Point(0, 0), 0, skia.Point(1, 1), 90, [0xFFFF00FF, 0xFFFFFF00], []), skia.Shader)
def shader(): return skia.GradientShader.MakeLinear( [skia.Point(0, 0), skia.Point(1, 1)], [0xFFFF00FF, 0xFFFFFF00], [])
def test_Canvas_drawPoints(canvas): points = [skia.Point(0, 0), skia.Point(1, 1)] canvas.drawPoints(skia.Canvas.kPoints_PointMode, points, skia.Paint())
def test_Vertices_uniqueID(vertices): assert isinstance(vertices.uniqueID(), int) def test_Vertices_bounds(vertices): assert isinstance(vertices.bounds(), skia.Rect) def test_Vertices_approximateSize(vertices): assert isinstance(vertices.approximateSize(), int) @pytest.mark.parametrize('args', [ ( skia.Vertices.kTriangles_VertexMode, [skia.Point(0, 0), skia.Point(1, 1), skia.Point(1, 0)], [skia.Point(1, 1), skia.Point(1, 0), skia.Point(0, 0)], [skia.ColorRED, skia.ColorRED, skia.ColorRED], [1], ), ( skia.Vertices.kTriangles_VertexMode, [skia.Point(0, 0), skia.Point(1, 1), skia.Point(1, 0)], [skia.Point(1, 1), skia.Point(1, 0), skia.Point(0, 0)], [skia.ColorRED, skia.ColorRED, skia.ColorRED], ), ( skia.Vertices.kTriangles_VertexMode, [skia.Point(0, 0), skia.Point(1, 1), skia.Point(1, 0)], ), ])
def test_TextBlobBuilder_allocRunPos(builder): builder.allocRunPos( skia.Font(), [0x20, 0x21], [skia.Point(0, 0), skia.Point(1, 0)])
def distance(p0, p1): return Point.Distance(skia.Point(p0.x, p0.y), skia.Point(p1.x, p1.y))
def test_TextBlob_MakeFromPosText(): assert isinstance( skia.TextBlob.MakeFromPosText( 'foo', [skia.Point(0, 0), skia.Point(1, 0), skia.Point(2, 0)], skia.Font()), skia.TextBlob)
def test_Point_init(): assert isinstance(skia.Point(4, 3), skia.Point) assert isinstance(skia.Point.Make(4, 3), skia.Point)
def test_Canvas_discard(canvas): canvas.discard() def test_Canvas_drawPaint(canvas): canvas.drawPaint(skia.Paint()) def test_Canvas_drawPoints(canvas): points = [skia.Point(0, 0), skia.Point(1, 1)] canvas.drawPoints(skia.Canvas.kPoints_PointMode, points, skia.Paint()) @pytest.mark.parametrize('args', [ (1, 1, skia.Paint()), (skia.Point(1, 1), skia.Paint()), ]) def test_Canvas_drawPoint(canvas, args): canvas.drawPoint(*args) @pytest.mark.parametrize('args', [ (0, 0, 1, 1, skia.Paint()), (skia.Point(0, 0), skia.Point(1, 1), skia.Paint()), ]) def test_Canvas_drawLine(canvas, args): canvas.drawLine(*args) def test_Canvas_drawRect(canvas): canvas.drawRect(skia.Rect(10, 10), skia.Paint())
def test_Matrix_get9(matrix): values = matrix.get9() assert isinstance(values, list) assert len(values) == 9 def test_Matrix_set9(matrix): assert isinstance(matrix.set9([0, 0, 0, 0, 0, 0, 0, 0, 0]), skia.Matrix) @pytest.mark.parametrize('args', [ ( 0, 0, ), (skia.Point(0, 0), ), ]) def test_Matrix_setTranslate(matrix, args): assert isinstance(matrix.setTranslate(*args), skia.Matrix) @pytest.mark.parametrize('args', [ ( 1, 1, 0, 0, ), ( 1, 1,
assert isinstance(skia.Shaders.Color(*args), skia.Shader) def test_Shaders_Blend(shader): assert isinstance( skia.Shaders.Blend(skia.BlendMode.kSrc, shader, shader), skia.Shader) def test_Shaders_Lerp(shader): assert isinstance( skia.Shaders.Lerp(0.5, shader, shader), skia.Shader) @pytest.mark.parametrize('args', [ ([skia.Point(0, 0), skia.Point(1, 1)], [0xFFFF00FF, 0xFFFFFF00], []), ([skia.Point(0, 0), skia.Point(1, 1)], [0xFFFF00FF, 0xFFFFFF00], [0, 1], skia.TileMode.kClamp, 0, skia.Matrix()), ]) def test_GradientShader_MakeLinear(args): assert isinstance(skia.GradientShader.MakeLinear(*args), skia.Shader) def test_GradientShader_MakeRadial(): assert isinstance(skia.GradientShader.MakeRadial( skia.Point(10, 10), 5, [0xFFFF00FF, 0xFFFFFF00], []), skia.Shader) def test_GradientShader_MakeTwoPointConical(): assert isinstance(skia.GradientShader.MakeTwoPointConical( skia.Point(0, 0), 0, skia.Point(1, 1), 90, [0xFFFF00FF, 0xFFFFFF00],
def test_Matrix_setPolyToPoly(matrix): assert isinstance( matrix.setPolyToPoly([skia.Point(100, 100)], [skia.Point(100, 100)]), bool)
def test_GradientShader_MakeRadial(): assert isinstance(skia.GradientShader.MakeRadial( skia.Point(10, 10), 5, [0xFFFF00FF, 0xFFFFFF00], []), skia.Shader)
def test_Matrix_mapPoints(matrix): assert isinstance(matrix.mapPoints([skia.Point(1, 1)]), list)
def draw_poligon(points: list[tuple[float, float]], color, *, fill=True, border_thickness=8): if fill: border_thickness = 0 p = skia.Path() p.addPoly([skia.Point(*p) for p in points], close=True) _canvas.drawPath(p, Color._paint(color, fill, border_thickness))
def test_Matrix_mapVectors(matrix): assert isinstance(matrix.mapVectors([skia.Point(0, 0)]), list)
def test_Path_isLine(path): p0 = skia.Point(0, 0) p1 = skia.Point(0, 0) assert isinstance(path.isLine(p0, p1), bool)
def test_Rect_setBounds(rect): rect.setBounds([(0, 0), (100, 100)]) def test_Rect_setBoundsCheck(rect): assert rect.setBoundsCheck([(0, 0), (100, 100)]) def test_Rect_setBoundsNoCheck(rect): rect.setBoundsNoCheck([(0, 0), (100, 100)]) @pytest.mark.parametrize('args', [ (skia.IRect(240, 120), ), (skia.Point(0, 0), skia.Point(240, 120)), ]) def test_Rect_set(rect, args): rect.set(*args) def test_Rect_setXYWH(rect): rect.setXYWH(0, 0, 240, 120) def test_Rect_setWH(rect): rect.setWH(240, 120) def test_Rect_setIWH(rect): rect.setIWH(240, 120)
def test_Path_getLastPt(path): assert isinstance(path.getLastPt(skia.Point(0, 0)), bool)
def __get_graphics_path(self, element, transform): #================================================= T = transform @ SVGTransform(element.attrib.get('transform')) if element.tag == SVG_NS('path'): tokens = re.sub('.', SVGTiler.__svg_path_matcher, element.attrib.get('d', '')).split() path = self.__path_from_tokens(tokens, T) elif element.tag == SVG_NS('rect'): (width, height) = T.scale_length( (length_as_pixels(element.attrib.get('width', 0)), length_as_pixels(element.attrib.get('height', 0)))) if width == 0 or height == 0: return None (rx, ry) = T.scale_length( (length_as_pixels(element.attrib.get('rx', 0)), length_as_pixels(element.attrib.get('ry', 0)))) if rx is None and ry is None: rx = ry = 0 elif ry is None: ry = rx elif rx is None: rx = ry rx = min(rx, width / 2) ry = min(ry, height / 2) (x, y) = T.transform_point( (length_as_pixels(element.attrib.get('x', 0)), length_as_pixels(element.attrib.get('y', 0)))) if rx == 0 and ry == 0: path = skia.Path.Rect((x, y, width, height)) else: path = skia.Path.RRect((x, y, width, height), rx, ry) elif element.tag == SVG_NS('line'): x1 = length_as_pixels(element.attrib.get('x1', 0)) y1 = length_as_pixels(element.attrib.get('y1', 0)) x2 = length_as_pixels(element.attrib.get('x2', 0)) y2 = length_as_pixels(element.attrib.get('y2', 0)) path = self.__path_from_tokens(['M', x1, y1, x2, y2], T) elif element.tag == SVG_NS('polyline'): points = element.attrib.get('points', '').replace(',', ' ').split() path = self.__path_from_tokens(['M'] + points, T) elif element.tag == SVG_NS('polygon'): points = element.attrib.get('points', '').replace(',', ' ').split() skia_points = [ skia.Point(*T.transform_point(points[n:n + 2])) for n in range(0, len(points), 2) ] path = skia.Path.Polygon(skia_points, True) elif element.tag == SVG_NS('circle'): r = length_as_pixels(element.attrib.get('r', 0)) if r == 0: return None (cx, cy) = T.transform_point( (length_as_pixels(element.attrib.get('cx', 0)), length_as_pixels(element.attrib.get('cy', 0)))) path = skia.Path.Circle(cx, cy, r) elif element.tag == SVG_NS('ellipse'): (rx, ry) = T.scale_length( (length_as_pixels(element.attrib.get('rx', 0)), length_as_pixels(element.attrib.get('ry', 0)))) if rx == 0 or ry == 0: return None (cx, cy) = T.transform_point( (length_as_pixels(element.attrib.get('cx', 0)), length_as_pixels(element.attrib.get('cy', 0)))) path = skia.Path.Oval((cx - rx, cy - ry, cx + rx, cy + ry)) return path
def test_Path_ConvertConicToQuads(path): assert isinstance( skia.Path.ConvertConicToQuads(skia.Point(0, 0), skia.Point(0, 1), skia.Point(1, 1), 1, 1), list)
def test_Path_ConvertConicToQuads(path): # See https://fiddle.skia.org/c/@Path_ConvertConicToQuads conic = [skia.Point(20, 170), skia.Point(80, 170), skia.Point(80, 230)] quads = skia.Path.ConvertConicToQuads(conic[0], conic[1], conic[2], .25, 1) assert isinstance(quads, list) assert len(quads) == 5