diff --git a/examples/svg/main.py b/examples/svg/main.py index 289919411..fa1242e58 100644 --- a/examples/svg/main.py +++ b/examples/svg/main.py @@ -3,8 +3,65 @@ from glob import glob from os.path import join, dirname from kivy.uix.scatter import Scatter from kivy.uix.widget import Widget +from kivy.uix.label import Label from kivy.app import App from kivy.graphics.svg import Svg +from kivy.core.window import Window +from kivy.uix.floatlayout import FloatLayout +from kivy.lang import Builder + + +smaa_ui = ''' +#:kivy 1.8.0 + +BoxLayout: + orientation: 'horizontal' + pos_hint: {'top': 1} + size_hint_y: None + height: '48dp' + padding: '2dp' + spacing: '2dp' + Label: + text: 'Quality:' + ToggleButton: + text: 'Low' + group: 'smaa-quality' + on_release: app.smaa.quality = 'low' + ToggleButton: + text: 'Medium' + group: 'smaa-quality' + on_release: app.smaa.quality = 'medium' + ToggleButton: + text: 'High' + group: 'smaa-quality' + on_release: app.smaa.quality = 'high' + ToggleButton: + text: 'Ultra' + group: 'smaa-quality' + state: 'down' + on_release: app.smaa.quality = 'ultra' + + Label: + text: 'Debug:' + ToggleButton: + text: 'None' + group: 'smaa-debug' + state: 'down' + on_release: app.smaa.debug = '' + ToggleButton: + text: 'Source' + group: 'smaa-debug' + on_release: app.smaa.debug = 'source' + ToggleButton: + text: 'Edges' + group: 'smaa-debug' + on_release: app.smaa.debug = 'edges' + ToggleButton: + text: 'Blend' + group: 'smaa-debug' + on_release: app.smaa.debug = 'blend' + +''' class SvgWidget(Scatter): @@ -12,22 +69,85 @@ class SvgWidget(Scatter): def __init__(self, filename): super(SvgWidget, self).__init__() with self.canvas: - Svg(filename) + svg = Svg(filename) + + self.size = svg.width, svg.height class SvgApp(App): def build(self): - root = Widget() + from kivy.garden.smaa import SMAA - filenames = sys.argv[1:] - if not filenames: - filenames = glob(join(dirname(__file__), '*.svg')) + Window.bind(on_keyboard=self._on_keyboard_handler) - for filename in filenames: - svg = SvgWidget(filename) - root.add_widget(svg) + self.smaa = SMAA() + self.effects = [self.smaa, Widget()] + self.effect_index = 0 + self.label = Label(text='SMAA', top=Window.height) + self.effect = effect = self.effects[0] + self.root = FloatLayout() + self.root.add_widget(effect) - return root + if 0: + from kivy.graphics import Color, Rectangle + wid = Widget(size=Window.size) + with wid.canvas: + Color(1, 1, 1, 1) + Rectangle(size=Window.size) + effect.add_widget(wid) + + if 1: + #from kivy.uix.image import Image + #root.add_widget(Image(source='data/logo/kivy-icon-512.png', size=(800, 600))) + + filenames = sys.argv[1:] + if not filenames: + filenames = glob(join(dirname(__file__), '*.svg')) + + for filename in filenames: + svg = SvgWidget(filename) + effect.add_widget(svg) + + effect.add_widget(self.label) + svg.scale = 5. + svg.center = Window.center + + if 0: + wid = Scatter(size=Window.size) + from kivy.graphics import Color, Triangle, Rectangle + with wid.canvas: + Color(0, 0, 0, 1) + Rectangle(size=Window.size) + Color(1, 1, 1, 1) + w, h = Window.size + cx, cy = w / 2., h / 2. + Triangle(points=[cx - w * 0.25, cy - h * 0.25, + cx, cy + h * 0.25, + cx + w * 0.25, cy - h * 0.25]) + effect.add_widget(wid) + + if 0: + from kivy.uix.button import Button + from kivy.uix.slider import Slider + effect.add_widget(Button(text='Hello World')) + effect.add_widget(Slider(pos=(200, 200))) + + + control_ui = Builder.load_string(smaa_ui) + self.root.add_widget(control_ui) + + def _on_keyboard_handler(self, instance, key, *args): + if key == 32: + self.effect_index = (self.effect_index + 1) % 2 + childrens = self.effect.children[:] + self.effect.clear_widgets() + self.root.remove_widget(self.effect) + self.effect = self.effects[self.effect_index] + self.root.add_widget(self.effect) + for child in reversed(childrens): + self.effect.add_widget(child) + self.label.text = self.effect.__class__.__name__ + Window.title = self.label.text if __name__ == '__main__': SvgApp().run() diff --git a/kivy/graphics/svg.pyx b/kivy/graphics/svg.pyx index 5357c6c58..985bb14f7 100644 --- a/kivy/graphics/svg.pyx +++ b/kivy/graphics/svg.pyx @@ -12,8 +12,8 @@ from xml.etree.cElementTree import parse from kivy.graphics.instructions cimport RenderContext from kivy.graphics.vertex_instructions import Mesh -DEF BEZIER_POINTS = 10 -DEF CIRCLE_POINTS = 24 +DEF BEZIER_POINTS = 64 # 10 +DEF CIRCLE_POINTS = 64 # 24 DEF TOLERANCE = 0.001 from cython.operator cimport dereference as deref, preincrement as inc @@ -265,7 +265,7 @@ cdef dict parse_style(string): cdef parse_color(c): cdef int r, g, b, a - if c is None or c == 'None': + if c is None or c == 'none': return None if c[0] == '#': c = c[1:] @@ -574,7 +574,6 @@ cdef class Svg(RenderContext): self.parse_element(e) def parse_element(self, e): - print 'parse_element()', e.tag self.fill = parse_color(e.get('fill')) self.stroke = parse_color(e.get('stroke')) oldopacity = self.opacity @@ -677,11 +676,9 @@ cdef class Svg(RenderContext): elif e.tag.endswith('linearGradient'): self.gradients[e.get('id')] = LinearGradient(e, self) - print 'added lineargradient', e.get('id') elif e.tag.endswith('radialGradient'): self.gradients[e.get('id')] = RadialGradient(e, self) - print 'added radialgradient', e.get('id') for c in e.getchildren(): self.parse_element(c) @@ -718,7 +715,6 @@ cdef class Svg(RenderContext): raise ValueError("Unallowed implicit command in %s, position %s" % ( pathdef, len(pathdef.split()) - len(elements))) - print 'execute command', command if command == 'M': # Moveto command. @@ -958,7 +954,8 @@ cdef class Svg(RenderContext): loop = [orig_loop[0]] for pt in orig_loop: if (pt[0] - loop[-1][0]) ** 2 + (pt[1] - loop[-1][1]) ** 2 > TOLERANCE: - loop.append(pt) + if pt not in loop: + loop.append(pt) path.append(loop) self.paths.append(( @@ -978,6 +975,9 @@ cdef class Svg(RenderContext): cdef vector[Triangle *].iterator it cdef vector[Triangle *] triangles + #print 'triangulate()' + #return [] + tris = [] for points in looplist: @@ -1010,14 +1010,10 @@ cdef class Svg(RenderContext): ('v_pos', 2, 'float'), ('v_color', 4, 'float')] - print '-> render!', len(self.paths) for path, stroke, tris, fill, transform in self.paths: - print 'we have multiples paths!', path, stroke, tris, fill if tris: - print fill if isinstance(fill, str): - print 'fill is', fill g = self.gradients[fill] fills = [g.interp(x) for x in tris] else: @@ -1049,6 +1045,7 @@ cdef class Svg(RenderContext): vtx = transform(vtx) vertices += [vtx[0], vtx[1], clr[0], clr[1], clr[2], clr[3]] + print 'add a mesh', len(indices), len(vertices) mesh = Mesh( fmt=vertex_format, indices=indices, diff --git a/setup.py b/setup.py index 93d5e1989..0fab91af3 100644 --- a/setup.py +++ b/setup.py @@ -428,7 +428,7 @@ graphics_dependencies = { 'stencil_instructions.pxd': ['instructions.pxd'], 'stencil_instructions.pyx': [ 'config.pxi', 'opcodes.pxi', 'c_opengl.pxd', 'c_opengl_debug.pxd'], - 'svg.pyx': ['config.pxi', 'common.pxi'], + 'svg.pyx': ['config.pxi', 'common.pxi', 'texture.pxd', 'instructions.pxd'], 'texture.pxd': ['c_opengl.pxd'], 'texture.pyx': [ 'config.pxi', 'common.pxi', 'opengl_utils_def.pxi', 'context.pxd',