vispy 0.15.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of vispy might be problematic. Click here for more details.

Files changed (521) hide show
  1. vispy/__init__.py +33 -0
  2. vispy/app/__init__.py +15 -0
  3. vispy/app/_default_app.py +76 -0
  4. vispy/app/_detect_eventloop.py +148 -0
  5. vispy/app/application.py +263 -0
  6. vispy/app/backends/__init__.py +52 -0
  7. vispy/app/backends/_egl.py +264 -0
  8. vispy/app/backends/_glfw.py +513 -0
  9. vispy/app/backends/_jupyter_rfb.py +278 -0
  10. vispy/app/backends/_offscreen_util.py +121 -0
  11. vispy/app/backends/_osmesa.py +235 -0
  12. vispy/app/backends/_pyglet.py +451 -0
  13. vispy/app/backends/_pyqt4.py +36 -0
  14. vispy/app/backends/_pyqt5.py +36 -0
  15. vispy/app/backends/_pyqt6.py +40 -0
  16. vispy/app/backends/_pyside.py +37 -0
  17. vispy/app/backends/_pyside2.py +52 -0
  18. vispy/app/backends/_pyside6.py +53 -0
  19. vispy/app/backends/_qt.py +1003 -0
  20. vispy/app/backends/_sdl2.py +444 -0
  21. vispy/app/backends/_template.py +244 -0
  22. vispy/app/backends/_test.py +8 -0
  23. vispy/app/backends/_tk.py +800 -0
  24. vispy/app/backends/_wx.py +476 -0
  25. vispy/app/backends/tests/__init__.py +0 -0
  26. vispy/app/backends/tests/test_offscreen_util.py +52 -0
  27. vispy/app/backends/tests/test_rfb.py +77 -0
  28. vispy/app/base.py +294 -0
  29. vispy/app/canvas.py +828 -0
  30. vispy/app/qt.py +92 -0
  31. vispy/app/tests/__init__.py +0 -0
  32. vispy/app/tests/qt-designer.ui +58 -0
  33. vispy/app/tests/test_app.py +442 -0
  34. vispy/app/tests/test_backends.py +164 -0
  35. vispy/app/tests/test_canvas.py +122 -0
  36. vispy/app/tests/test_context.py +92 -0
  37. vispy/app/tests/test_qt.py +47 -0
  38. vispy/app/tests/test_simultaneous.py +134 -0
  39. vispy/app/timer.py +174 -0
  40. vispy/color/__init__.py +17 -0
  41. vispy/color/_color_dict.py +193 -0
  42. vispy/color/color_array.py +447 -0
  43. vispy/color/color_space.py +181 -0
  44. vispy/color/colormap.py +1213 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +378 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1522 -0
  50. vispy/ext/cubehelix.py +138 -0
  51. vispy/ext/egl.py +375 -0
  52. vispy/ext/fontconfig.py +118 -0
  53. vispy/ext/gdi32plus.py +206 -0
  54. vispy/ext/osmesa.py +105 -0
  55. vispy/geometry/__init__.py +23 -0
  56. vispy/geometry/_triangulation_debugger.py +171 -0
  57. vispy/geometry/calculations.py +162 -0
  58. vispy/geometry/curves.py +399 -0
  59. vispy/geometry/generation.py +643 -0
  60. vispy/geometry/isocurve.py +175 -0
  61. vispy/geometry/isosurface.py +465 -0
  62. vispy/geometry/meshdata.py +700 -0
  63. vispy/geometry/normals.py +78 -0
  64. vispy/geometry/parametric.py +56 -0
  65. vispy/geometry/polygon.py +137 -0
  66. vispy/geometry/rect.py +210 -0
  67. vispy/geometry/tests/__init__.py +0 -0
  68. vispy/geometry/tests/test_calculations.py +23 -0
  69. vispy/geometry/tests/test_generation.py +56 -0
  70. vispy/geometry/tests/test_meshdata.py +106 -0
  71. vispy/geometry/tests/test_triangulation.py +594 -0
  72. vispy/geometry/torusknot.py +142 -0
  73. vispy/geometry/triangulation.py +876 -0
  74. vispy/gloo/__init__.py +56 -0
  75. vispy/gloo/buffer.py +505 -0
  76. vispy/gloo/context.py +272 -0
  77. vispy/gloo/framebuffer.py +257 -0
  78. vispy/gloo/gl/__init__.py +234 -0
  79. vispy/gloo/gl/_constants.py +332 -0
  80. vispy/gloo/gl/_es2.py +986 -0
  81. vispy/gloo/gl/_gl2.py +1365 -0
  82. vispy/gloo/gl/_proxy.py +499 -0
  83. vispy/gloo/gl/_pyopengl2.py +362 -0
  84. vispy/gloo/gl/dummy.py +24 -0
  85. vispy/gloo/gl/es2.py +62 -0
  86. vispy/gloo/gl/gl2.py +98 -0
  87. vispy/gloo/gl/glplus.py +168 -0
  88. vispy/gloo/gl/pyopengl2.py +97 -0
  89. vispy/gloo/gl/tests/__init__.py +0 -0
  90. vispy/gloo/gl/tests/test_basics.py +282 -0
  91. vispy/gloo/gl/tests/test_functionality.py +568 -0
  92. vispy/gloo/gl/tests/test_names.py +246 -0
  93. vispy/gloo/gl/tests/test_use.py +71 -0
  94. vispy/gloo/glir.py +1824 -0
  95. vispy/gloo/globject.py +101 -0
  96. vispy/gloo/preprocessor.py +67 -0
  97. vispy/gloo/program.py +543 -0
  98. vispy/gloo/tests/__init__.py +0 -0
  99. vispy/gloo/tests/test_buffer.py +558 -0
  100. vispy/gloo/tests/test_context.py +119 -0
  101. vispy/gloo/tests/test_framebuffer.py +195 -0
  102. vispy/gloo/tests/test_glir.py +307 -0
  103. vispy/gloo/tests/test_globject.py +35 -0
  104. vispy/gloo/tests/test_program.py +302 -0
  105. vispy/gloo/tests/test_texture.py +732 -0
  106. vispy/gloo/tests/test_use_gloo.py +187 -0
  107. vispy/gloo/tests/test_util.py +60 -0
  108. vispy/gloo/tests/test_wrappers.py +261 -0
  109. vispy/gloo/texture.py +1046 -0
  110. vispy/gloo/util.py +129 -0
  111. vispy/gloo/wrappers.py +762 -0
  112. vispy/glsl/__init__.py +42 -0
  113. vispy/glsl/antialias/antialias.glsl +7 -0
  114. vispy/glsl/antialias/cap-butt.glsl +31 -0
  115. vispy/glsl/antialias/cap-round.glsl +29 -0
  116. vispy/glsl/antialias/cap-square.glsl +30 -0
  117. vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
  118. vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
  119. vispy/glsl/antialias/cap.glsl +67 -0
  120. vispy/glsl/antialias/caps.glsl +67 -0
  121. vispy/glsl/antialias/filled.glsl +50 -0
  122. vispy/glsl/antialias/outline.glsl +40 -0
  123. vispy/glsl/antialias/stroke.glsl +43 -0
  124. vispy/glsl/arrowheads/angle.glsl +99 -0
  125. vispy/glsl/arrowheads/arrowheads.frag +60 -0
  126. vispy/glsl/arrowheads/arrowheads.glsl +12 -0
  127. vispy/glsl/arrowheads/arrowheads.vert +83 -0
  128. vispy/glsl/arrowheads/curved.glsl +48 -0
  129. vispy/glsl/arrowheads/inhibitor.glsl +26 -0
  130. vispy/glsl/arrowheads/stealth.glsl +46 -0
  131. vispy/glsl/arrowheads/triangle.glsl +97 -0
  132. vispy/glsl/arrowheads/util.glsl +13 -0
  133. vispy/glsl/arrows/angle-30.glsl +12 -0
  134. vispy/glsl/arrows/angle-60.glsl +12 -0
  135. vispy/glsl/arrows/angle-90.glsl +12 -0
  136. vispy/glsl/arrows/arrow.frag +39 -0
  137. vispy/glsl/arrows/arrow.vert +49 -0
  138. vispy/glsl/arrows/arrows.glsl +17 -0
  139. vispy/glsl/arrows/common.glsl +187 -0
  140. vispy/glsl/arrows/curved.glsl +63 -0
  141. vispy/glsl/arrows/stealth.glsl +50 -0
  142. vispy/glsl/arrows/triangle-30.glsl +12 -0
  143. vispy/glsl/arrows/triangle-60.glsl +12 -0
  144. vispy/glsl/arrows/triangle-90.glsl +12 -0
  145. vispy/glsl/arrows/util.glsl +98 -0
  146. vispy/glsl/build_spatial_filters.py +660 -0
  147. vispy/glsl/collections/agg-fast-path.frag +20 -0
  148. vispy/glsl/collections/agg-fast-path.vert +78 -0
  149. vispy/glsl/collections/agg-glyph.frag +60 -0
  150. vispy/glsl/collections/agg-glyph.vert +33 -0
  151. vispy/glsl/collections/agg-marker.frag +35 -0
  152. vispy/glsl/collections/agg-marker.vert +48 -0
  153. vispy/glsl/collections/agg-path.frag +55 -0
  154. vispy/glsl/collections/agg-path.vert +166 -0
  155. vispy/glsl/collections/agg-point.frag +21 -0
  156. vispy/glsl/collections/agg-point.vert +35 -0
  157. vispy/glsl/collections/agg-segment.frag +32 -0
  158. vispy/glsl/collections/agg-segment.vert +75 -0
  159. vispy/glsl/collections/marker.frag +38 -0
  160. vispy/glsl/collections/marker.vert +48 -0
  161. vispy/glsl/collections/raw-path.frag +15 -0
  162. vispy/glsl/collections/raw-path.vert +24 -0
  163. vispy/glsl/collections/raw-point.frag +14 -0
  164. vispy/glsl/collections/raw-point.vert +31 -0
  165. vispy/glsl/collections/raw-segment.frag +18 -0
  166. vispy/glsl/collections/raw-segment.vert +26 -0
  167. vispy/glsl/collections/raw-triangle.frag +13 -0
  168. vispy/glsl/collections/raw-triangle.vert +26 -0
  169. vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
  170. vispy/glsl/collections/sdf-glyph.frag +80 -0
  171. vispy/glsl/collections/sdf-glyph.vert +59 -0
  172. vispy/glsl/collections/tick-labels.vert +71 -0
  173. vispy/glsl/colormaps/autumn.glsl +20 -0
  174. vispy/glsl/colormaps/blues.glsl +20 -0
  175. vispy/glsl/colormaps/color-space.glsl +17 -0
  176. vispy/glsl/colormaps/colormaps.glsl +24 -0
  177. vispy/glsl/colormaps/cool.glsl +20 -0
  178. vispy/glsl/colormaps/fire.glsl +21 -0
  179. vispy/glsl/colormaps/gray.glsl +20 -0
  180. vispy/glsl/colormaps/greens.glsl +20 -0
  181. vispy/glsl/colormaps/hot.glsl +22 -0
  182. vispy/glsl/colormaps/ice.glsl +20 -0
  183. vispy/glsl/colormaps/icefire.glsl +23 -0
  184. vispy/glsl/colormaps/parse.py +40 -0
  185. vispy/glsl/colormaps/reds.glsl +20 -0
  186. vispy/glsl/colormaps/spring.glsl +20 -0
  187. vispy/glsl/colormaps/summer.glsl +20 -0
  188. vispy/glsl/colormaps/user.glsl +22 -0
  189. vispy/glsl/colormaps/util.glsl +41 -0
  190. vispy/glsl/colormaps/wheel.glsl +21 -0
  191. vispy/glsl/colormaps/winter.glsl +20 -0
  192. vispy/glsl/lines/agg.frag +320 -0
  193. vispy/glsl/lines/agg.vert +241 -0
  194. vispy/glsl/markers/arrow.glsl +12 -0
  195. vispy/glsl/markers/asterisk.glsl +16 -0
  196. vispy/glsl/markers/chevron.glsl +14 -0
  197. vispy/glsl/markers/clover.glsl +20 -0
  198. vispy/glsl/markers/club.glsl +31 -0
  199. vispy/glsl/markers/cross.glsl +17 -0
  200. vispy/glsl/markers/diamond.glsl +12 -0
  201. vispy/glsl/markers/disc.glsl +9 -0
  202. vispy/glsl/markers/ellipse.glsl +67 -0
  203. vispy/glsl/markers/hbar.glsl +9 -0
  204. vispy/glsl/markers/heart.glsl +15 -0
  205. vispy/glsl/markers/infinity.glsl +15 -0
  206. vispy/glsl/markers/marker-sdf.frag +74 -0
  207. vispy/glsl/markers/marker-sdf.vert +41 -0
  208. vispy/glsl/markers/marker.frag +36 -0
  209. vispy/glsl/markers/marker.vert +46 -0
  210. vispy/glsl/markers/markers.glsl +24 -0
  211. vispy/glsl/markers/pin.glsl +18 -0
  212. vispy/glsl/markers/ring.glsl +11 -0
  213. vispy/glsl/markers/spade.glsl +28 -0
  214. vispy/glsl/markers/square.glsl +10 -0
  215. vispy/glsl/markers/tag.glsl +11 -0
  216. vispy/glsl/markers/triangle.glsl +14 -0
  217. vispy/glsl/markers/vbar.glsl +9 -0
  218. vispy/glsl/math/circle-through-2-points.glsl +30 -0
  219. vispy/glsl/math/constants.glsl +48 -0
  220. vispy/glsl/math/double.glsl +114 -0
  221. vispy/glsl/math/functions.glsl +20 -0
  222. vispy/glsl/math/point-to-line-distance.glsl +31 -0
  223. vispy/glsl/math/point-to-line-projection.glsl +29 -0
  224. vispy/glsl/math/signed-line-distance.glsl +27 -0
  225. vispy/glsl/math/signed-segment-distance.glsl +30 -0
  226. vispy/glsl/misc/regular-grid.frag +244 -0
  227. vispy/glsl/misc/spatial-filters.frag +1407 -0
  228. vispy/glsl/misc/viewport-NDC.glsl +20 -0
  229. vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
  230. vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
  231. vispy/glsl/transforms/hammer.glsl +44 -0
  232. vispy/glsl/transforms/identity.glsl +6 -0
  233. vispy/glsl/transforms/identity_forward.glsl +23 -0
  234. vispy/glsl/transforms/identity_inverse.glsl +23 -0
  235. vispy/glsl/transforms/linear-scale.glsl +127 -0
  236. vispy/glsl/transforms/log-scale.glsl +126 -0
  237. vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
  238. vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
  239. vispy/glsl/transforms/panzoom.glsl +10 -0
  240. vispy/glsl/transforms/polar.glsl +41 -0
  241. vispy/glsl/transforms/position.glsl +44 -0
  242. vispy/glsl/transforms/power-scale.glsl +139 -0
  243. vispy/glsl/transforms/projection.glsl +7 -0
  244. vispy/glsl/transforms/pvm.glsl +13 -0
  245. vispy/glsl/transforms/rotate.glsl +45 -0
  246. vispy/glsl/transforms/trackball.glsl +15 -0
  247. vispy/glsl/transforms/translate.glsl +35 -0
  248. vispy/glsl/transforms/transverse_mercator.glsl +38 -0
  249. vispy/glsl/transforms/viewport-clipping.glsl +14 -0
  250. vispy/glsl/transforms/viewport-transform.glsl +16 -0
  251. vispy/glsl/transforms/viewport.glsl +50 -0
  252. vispy/glsl/transforms/x.glsl +24 -0
  253. vispy/glsl/transforms/y.glsl +19 -0
  254. vispy/glsl/transforms/z.glsl +14 -0
  255. vispy/io/__init__.py +20 -0
  256. vispy/io/_data/spatial-filters.npy +0 -0
  257. vispy/io/datasets.py +94 -0
  258. vispy/io/image.py +231 -0
  259. vispy/io/mesh.py +122 -0
  260. vispy/io/stl.py +167 -0
  261. vispy/io/tests/__init__.py +0 -0
  262. vispy/io/tests/test_image.py +47 -0
  263. vispy/io/tests/test_io.py +121 -0
  264. vispy/io/wavefront.py +350 -0
  265. vispy/plot/__init__.py +36 -0
  266. vispy/plot/fig.py +58 -0
  267. vispy/plot/plotwidget.py +522 -0
  268. vispy/plot/tests/__init__.py +0 -0
  269. vispy/plot/tests/test_plot.py +46 -0
  270. vispy/scene/__init__.py +43 -0
  271. vispy/scene/cameras/__init__.py +27 -0
  272. vispy/scene/cameras/_base.py +38 -0
  273. vispy/scene/cameras/arcball.py +105 -0
  274. vispy/scene/cameras/base_camera.py +551 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +311 -0
  278. vispy/scene/cameras/perspective.py +338 -0
  279. vispy/scene/cameras/tests/__init__.py +0 -0
  280. vispy/scene/cameras/tests/test_cameras.py +27 -0
  281. vispy/scene/cameras/tests/test_link.py +53 -0
  282. vispy/scene/cameras/tests/test_perspective.py +122 -0
  283. vispy/scene/cameras/turntable.py +183 -0
  284. vispy/scene/canvas.py +639 -0
  285. vispy/scene/events.py +85 -0
  286. vispy/scene/node.py +644 -0
  287. vispy/scene/subscene.py +20 -0
  288. vispy/scene/tests/__init__.py +0 -0
  289. vispy/scene/tests/test_canvas.py +119 -0
  290. vispy/scene/tests/test_node.py +142 -0
  291. vispy/scene/tests/test_visuals.py +141 -0
  292. vispy/scene/visuals.py +276 -0
  293. vispy/scene/widgets/__init__.py +18 -0
  294. vispy/scene/widgets/anchor.py +25 -0
  295. vispy/scene/widgets/axis.py +88 -0
  296. vispy/scene/widgets/colorbar.py +176 -0
  297. vispy/scene/widgets/console.py +351 -0
  298. vispy/scene/widgets/grid.py +509 -0
  299. vispy/scene/widgets/label.py +50 -0
  300. vispy/scene/widgets/tests/__init__.py +0 -0
  301. vispy/scene/widgets/tests/test_colorbar.py +47 -0
  302. vispy/scene/widgets/viewbox.py +199 -0
  303. vispy/scene/widgets/widget.py +478 -0
  304. vispy/testing/__init__.py +51 -0
  305. vispy/testing/_runners.py +448 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +494 -0
  308. vispy/testing/rendered_array_tester.py +85 -0
  309. vispy/testing/tests/__init__.py +0 -0
  310. vispy/testing/tests/test_testing.py +20 -0
  311. vispy/util/__init__.py +32 -0
  312. vispy/util/bunch.py +15 -0
  313. vispy/util/check_environment.py +57 -0
  314. vispy/util/config.py +490 -0
  315. vispy/util/dpi/__init__.py +19 -0
  316. vispy/util/dpi/_linux.py +69 -0
  317. vispy/util/dpi/_quartz.py +26 -0
  318. vispy/util/dpi/_win32.py +34 -0
  319. vispy/util/dpi/tests/__init__.py +0 -0
  320. vispy/util/dpi/tests/test_dpi.py +16 -0
  321. vispy/util/eq.py +41 -0
  322. vispy/util/event.py +774 -0
  323. vispy/util/fetching.py +276 -0
  324. vispy/util/filter.py +44 -0
  325. vispy/util/fonts/__init__.py +14 -0
  326. vispy/util/fonts/_freetype.py +73 -0
  327. vispy/util/fonts/_quartz.py +192 -0
  328. vispy/util/fonts/_triage.py +36 -0
  329. vispy/util/fonts/_vispy_fonts.py +20 -0
  330. vispy/util/fonts/_win32.py +105 -0
  331. vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
  332. vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
  333. vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
  334. vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
  335. vispy/util/fonts/tests/__init__.py +0 -0
  336. vispy/util/fonts/tests/test_font.py +45 -0
  337. vispy/util/fourier.py +69 -0
  338. vispy/util/frozen.py +25 -0
  339. vispy/util/gallery_scraper.py +268 -0
  340. vispy/util/keys.py +91 -0
  341. vispy/util/logs.py +358 -0
  342. vispy/util/osmesa_gl.py +17 -0
  343. vispy/util/profiler.py +135 -0
  344. vispy/util/ptime.py +16 -0
  345. vispy/util/quaternion.py +229 -0
  346. vispy/util/svg/__init__.py +18 -0
  347. vispy/util/svg/base.py +20 -0
  348. vispy/util/svg/color.py +219 -0
  349. vispy/util/svg/element.py +51 -0
  350. vispy/util/svg/geometry.py +478 -0
  351. vispy/util/svg/group.py +66 -0
  352. vispy/util/svg/length.py +81 -0
  353. vispy/util/svg/number.py +25 -0
  354. vispy/util/svg/path.py +332 -0
  355. vispy/util/svg/shapes.py +57 -0
  356. vispy/util/svg/style.py +59 -0
  357. vispy/util/svg/svg.py +40 -0
  358. vispy/util/svg/transform.py +223 -0
  359. vispy/util/svg/transformable.py +28 -0
  360. vispy/util/svg/viewport.py +73 -0
  361. vispy/util/tests/__init__.py +0 -0
  362. vispy/util/tests/test_config.py +58 -0
  363. vispy/util/tests/test_docstring_parameters.py +123 -0
  364. vispy/util/tests/test_emitter_group.py +262 -0
  365. vispy/util/tests/test_event_emitter.py +743 -0
  366. vispy/util/tests/test_fourier.py +35 -0
  367. vispy/util/tests/test_gallery_scraper.py +112 -0
  368. vispy/util/tests/test_import.py +127 -0
  369. vispy/util/tests/test_key.py +22 -0
  370. vispy/util/tests/test_logging.py +45 -0
  371. vispy/util/tests/test_run.py +14 -0
  372. vispy/util/tests/test_transforms.py +42 -0
  373. vispy/util/tests/test_vispy.py +48 -0
  374. vispy/util/transforms.py +201 -0
  375. vispy/util/wrappers.py +155 -0
  376. vispy/version.py +21 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +487 -0
  379. vispy/visuals/axis.py +678 -0
  380. vispy/visuals/border.py +208 -0
  381. vispy/visuals/box.py +79 -0
  382. vispy/visuals/collections/__init__.py +30 -0
  383. vispy/visuals/collections/agg_fast_path_collection.py +219 -0
  384. vispy/visuals/collections/agg_path_collection.py +197 -0
  385. vispy/visuals/collections/agg_point_collection.py +52 -0
  386. vispy/visuals/collections/agg_segment_collection.py +142 -0
  387. vispy/visuals/collections/array_list.py +401 -0
  388. vispy/visuals/collections/base_collection.py +482 -0
  389. vispy/visuals/collections/collection.py +253 -0
  390. vispy/visuals/collections/path_collection.py +23 -0
  391. vispy/visuals/collections/point_collection.py +19 -0
  392. vispy/visuals/collections/polygon_collection.py +25 -0
  393. vispy/visuals/collections/raw_path_collection.py +119 -0
  394. vispy/visuals/collections/raw_point_collection.py +113 -0
  395. vispy/visuals/collections/raw_polygon_collection.py +77 -0
  396. vispy/visuals/collections/raw_segment_collection.py +112 -0
  397. vispy/visuals/collections/raw_triangle_collection.py +78 -0
  398. vispy/visuals/collections/segment_collection.py +19 -0
  399. vispy/visuals/collections/triangle_collection.py +16 -0
  400. vispy/visuals/collections/util.py +168 -0
  401. vispy/visuals/colorbar.py +699 -0
  402. vispy/visuals/cube.py +41 -0
  403. vispy/visuals/ellipse.py +162 -0
  404. vispy/visuals/filters/__init__.py +10 -0
  405. vispy/visuals/filters/base_filter.py +242 -0
  406. vispy/visuals/filters/clipper.py +60 -0
  407. vispy/visuals/filters/clipping_planes.py +122 -0
  408. vispy/visuals/filters/color.py +181 -0
  409. vispy/visuals/filters/markers.py +28 -0
  410. vispy/visuals/filters/mesh.py +801 -0
  411. vispy/visuals/filters/picking.py +60 -0
  412. vispy/visuals/filters/tests/__init__.py +3 -0
  413. vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
  414. vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
  415. vispy/visuals/glsl/__init__.py +1 -0
  416. vispy/visuals/glsl/antialiasing.py +133 -0
  417. vispy/visuals/glsl/color.py +63 -0
  418. vispy/visuals/graphs/__init__.py +1 -0
  419. vispy/visuals/graphs/graph.py +240 -0
  420. vispy/visuals/graphs/layouts/__init__.py +55 -0
  421. vispy/visuals/graphs/layouts/circular.py +49 -0
  422. vispy/visuals/graphs/layouts/force_directed.py +211 -0
  423. vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
  424. vispy/visuals/graphs/layouts/random.py +52 -0
  425. vispy/visuals/graphs/tests/__init__.py +1 -0
  426. vispy/visuals/graphs/tests/test_layouts.py +139 -0
  427. vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
  428. vispy/visuals/graphs/util.py +120 -0
  429. vispy/visuals/gridlines.py +161 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +701 -0
  433. vispy/visuals/image_complex.py +130 -0
  434. vispy/visuals/infinite_line.py +199 -0
  435. vispy/visuals/instanced_mesh.py +152 -0
  436. vispy/visuals/isocurve.py +213 -0
  437. vispy/visuals/isoline.py +241 -0
  438. vispy/visuals/isosurface.py +113 -0
  439. vispy/visuals/line/__init__.py +6 -0
  440. vispy/visuals/line/arrow.py +289 -0
  441. vispy/visuals/line/dash_atlas.py +90 -0
  442. vispy/visuals/line/line.py +545 -0
  443. vispy/visuals/line_plot.py +135 -0
  444. vispy/visuals/linear_region.py +199 -0
  445. vispy/visuals/markers.py +819 -0
  446. vispy/visuals/mesh.py +373 -0
  447. vispy/visuals/mesh_normals.py +159 -0
  448. vispy/visuals/plane.py +54 -0
  449. vispy/visuals/polygon.py +145 -0
  450. vispy/visuals/rectangle.py +196 -0
  451. vispy/visuals/regular_polygon.py +56 -0
  452. vispy/visuals/scrolling_lines.py +197 -0
  453. vispy/visuals/shaders/__init__.py +17 -0
  454. vispy/visuals/shaders/compiler.py +206 -0
  455. vispy/visuals/shaders/expression.py +99 -0
  456. vispy/visuals/shaders/function.py +788 -0
  457. vispy/visuals/shaders/multiprogram.py +145 -0
  458. vispy/visuals/shaders/parsing.py +140 -0
  459. vispy/visuals/shaders/program.py +161 -0
  460. vispy/visuals/shaders/shader_object.py +162 -0
  461. vispy/visuals/shaders/tests/__init__.py +0 -0
  462. vispy/visuals/shaders/tests/test_function.py +486 -0
  463. vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
  464. vispy/visuals/shaders/tests/test_parsing.py +57 -0
  465. vispy/visuals/shaders/variable.py +272 -0
  466. vispy/visuals/spectrogram.py +169 -0
  467. vispy/visuals/sphere.py +80 -0
  468. vispy/visuals/surface_plot.py +192 -0
  469. vispy/visuals/tests/__init__.py +0 -0
  470. vispy/visuals/tests/test_arrows.py +109 -0
  471. vispy/visuals/tests/test_axis.py +120 -0
  472. vispy/visuals/tests/test_collections.py +15 -0
  473. vispy/visuals/tests/test_colorbar.py +179 -0
  474. vispy/visuals/tests/test_colormap.py +97 -0
  475. vispy/visuals/tests/test_ellipse.py +122 -0
  476. vispy/visuals/tests/test_gridlines.py +30 -0
  477. vispy/visuals/tests/test_histogram.py +24 -0
  478. vispy/visuals/tests/test_image.py +392 -0
  479. vispy/visuals/tests/test_image_complex.py +36 -0
  480. vispy/visuals/tests/test_infinite_line.py +53 -0
  481. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  482. vispy/visuals/tests/test_isosurface.py +22 -0
  483. vispy/visuals/tests/test_linear_region.py +152 -0
  484. vispy/visuals/tests/test_markers.py +54 -0
  485. vispy/visuals/tests/test_mesh.py +261 -0
  486. vispy/visuals/tests/test_mesh_normals.py +218 -0
  487. vispy/visuals/tests/test_polygon.py +112 -0
  488. vispy/visuals/tests/test_rectangle.py +163 -0
  489. vispy/visuals/tests/test_regular_polygon.py +111 -0
  490. vispy/visuals/tests/test_scalable_textures.py +196 -0
  491. vispy/visuals/tests/test_sdf.py +73 -0
  492. vispy/visuals/tests/test_spectrogram.py +42 -0
  493. vispy/visuals/tests/test_surface_plot.py +57 -0
  494. vispy/visuals/tests/test_text.py +95 -0
  495. vispy/visuals/tests/test_volume.py +542 -0
  496. vispy/visuals/tests/test_windbarb.py +33 -0
  497. vispy/visuals/text/__init__.py +7 -0
  498. vispy/visuals/text/_sdf_cpu.cp313-win_amd64.pyd +0 -0
  499. vispy/visuals/text/_sdf_cpu.pyx +112 -0
  500. vispy/visuals/text/_sdf_gpu.py +316 -0
  501. vispy/visuals/text/text.py +675 -0
  502. vispy/visuals/transforms/__init__.py +34 -0
  503. vispy/visuals/transforms/_util.py +191 -0
  504. vispy/visuals/transforms/base_transform.py +233 -0
  505. vispy/visuals/transforms/chain.py +300 -0
  506. vispy/visuals/transforms/interactive.py +98 -0
  507. vispy/visuals/transforms/linear.py +564 -0
  508. vispy/visuals/transforms/nonlinear.py +398 -0
  509. vispy/visuals/transforms/tests/__init__.py +0 -0
  510. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  511. vispy/visuals/transforms/transform_system.py +339 -0
  512. vispy/visuals/tube.py +173 -0
  513. vispy/visuals/visual.py +923 -0
  514. vispy/visuals/volume.py +1366 -0
  515. vispy/visuals/windbarb.py +291 -0
  516. vispy/visuals/xyz_axis.py +34 -0
  517. vispy-0.15.0.dist-info/METADATA +243 -0
  518. vispy-0.15.0.dist-info/RECORD +521 -0
  519. vispy-0.15.0.dist-info/WHEEL +5 -0
  520. vispy-0.15.0.dist-info/licenses/LICENSE.txt +36 -0
  521. vispy-0.15.0.dist-info/top_level.txt +1 -0
vispy/util/svg/path.py ADDED
@@ -0,0 +1,332 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -----------------------------------------------------------------------------
3
+ # Copyright (c) 2014, Nicolas P. Rougier
4
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
5
+ # -----------------------------------------------------------------------------
6
+ import re
7
+ import math
8
+ import numpy as np
9
+
10
+ from . import geometry
11
+ from . geometry import epsilon
12
+ from . transformable import Transformable
13
+
14
+
15
+ # ----------------------------------------------------------------- Command ---
16
+ class Command(object):
17
+
18
+ def __repr__(self):
19
+ s = '%s ' % self._command
20
+ for arg in self._args:
21
+ s += "%.2f " % arg
22
+ return s
23
+
24
+ def origin(self, current=None, previous=None):
25
+ relative = self._command in "mlvhcsqtaz"
26
+
27
+ if relative and current:
28
+ return current
29
+ else:
30
+ return 0.0, 0.0
31
+
32
+
33
+ # -------------------------------------------------------------------- Line ---
34
+ class Line(Command):
35
+
36
+ def __init__(self, x=0, y=0, relative=True):
37
+ self._command = 'l' if relative else 'L'
38
+ self._args = [x, y]
39
+
40
+ def vertices(self, current, previous=None):
41
+ ox, oy = self.origin(current)
42
+ x, y = self._args
43
+ self.previous = x, y
44
+
45
+ return (ox + x, oy + y),
46
+
47
+
48
+ # ------------------------------------------------------------------- VLine ---
49
+ class VLine(Command):
50
+
51
+ def __init__(self, y=0, relative=True):
52
+ self._command = 'v' if relative else 'V'
53
+ self._args = [y]
54
+
55
+ def vertices(self, current, previous=None):
56
+ ox, oy = self.origin(current)
57
+ y = self._args[0]
58
+ self.previous = ox, oy + y
59
+
60
+ return (ox, oy + y),
61
+
62
+
63
+ # ------------------------------------------------------------------- HLine ---
64
+ class HLine(Command):
65
+
66
+ def __init__(self, x=0, relative=True):
67
+ self._command = 'h' if relative else 'H'
68
+ self._args = [x]
69
+
70
+ def vertices(self, current, previous=None):
71
+ ox, oy = self.origin(current)
72
+ x = self._args[0]
73
+ self.previous = ox + x, oy
74
+
75
+ return (ox + x, oy),
76
+
77
+
78
+ # -------------------------------------------------------------------- Move ---
79
+ class Move(Command):
80
+
81
+ def __init__(self, x=0, y=0, relative=True):
82
+ self._command = 'm' if relative else 'M'
83
+ self._args = [x, y]
84
+
85
+ def vertices(self, current, previous=None):
86
+ ox, oy = self.origin(current)
87
+ x, y = self._args
88
+ x, y = x + ox, y + oy
89
+ self.previous = x, y
90
+ return (x, y),
91
+
92
+
93
+ # ------------------------------------------------------------------- Close ---
94
+ class Close(Command):
95
+
96
+ def __init__(self, relative=True):
97
+ self._command = 'z' if relative else 'Z'
98
+ self._args = []
99
+
100
+ def vertices(self, current, previous=None):
101
+ self.previous = current
102
+ return []
103
+
104
+
105
+ # --------------------------------------------------------------------- Arc ---
106
+ class Arc(Command):
107
+
108
+ def __init__(self, r1=1, r2=1, angle=2 * math.pi, large=True, sweep=True,
109
+ x=0, y=0, relative=True):
110
+ self._command = 'a' if relative else 'A'
111
+ self._args = [r1, r2, angle, large, sweep, x, y]
112
+
113
+ def vertices(self, current, previous=None):
114
+ ox, oy = self.origin(current)
115
+ rx, ry, angle, large, sweep, x, y = self._args
116
+ x, y = x + ox, y + oy
117
+ x0, y0 = current
118
+ self.previous = x, y
119
+ vertices = geometry.elliptical_arc(
120
+ x0, y0, rx, ry, angle, large, sweep, x, y)
121
+ return vertices[1:]
122
+
123
+
124
+ # ------------------------------------------------------------------- Cubic ---
125
+ class Cubic(Command):
126
+
127
+ def __init__(self, x1=0, y1=0, x2=0, y2=0, x3=0, y3=0, relative=True):
128
+ self._command = 'c' if relative else 'C'
129
+ self._args = [x1, y1, x2, y2, x3, y3]
130
+
131
+ def vertices(self, current, previous=None):
132
+ ox, oy = self.origin(current)
133
+ x0, y0 = current
134
+ x1, y1, x2, y2, x3, y3 = self._args
135
+ x1, y1 = x1 + ox, y1 + oy
136
+ x2, y2 = x2 + ox, y2 + oy
137
+ x3, y3 = x3 + ox, y3 + oy
138
+ self.previous = x2, y2
139
+ vertices = geometry.cubic((x0, y0), (x1, y1), (x2, y2), (x3, y3))
140
+ return vertices[1:]
141
+
142
+
143
+ # --------------------------------------------------------------- Quadratic ---
144
+ class Quadratic(Command):
145
+
146
+ def __init__(self, x1=0, y1=0, x2=0, y2=0, relative=True):
147
+ self._command = 'q' if relative else 'Q'
148
+ self._args = [x1, y1, x2, y2]
149
+
150
+ def vertices(self, current, last_control_point=None):
151
+ ox, oy = self.origin(current)
152
+ x1, y1, x2, y2 = self._args
153
+ x0, y0 = current
154
+ x1, y1 = x1 + ox, y1 + oy
155
+ x2, y2 = x2 + ox, y2 + oy
156
+ self.previous = x1, y1
157
+ vertices = geometry.quadratic((x0, y0), (x1, y1), (x2, y2))
158
+
159
+ return vertices[1:]
160
+
161
+
162
+ # ------------------------------------------------------------- SmoothCubic ---
163
+ class SmoothCubic(Command):
164
+
165
+ def __init__(self, x2=0, y2=0, x3=0, y3=0, relative=True):
166
+ self._command = 's' if relative else 'S'
167
+ self._args = [x2, y2, x3, y3]
168
+
169
+ def vertices(self, current, previous):
170
+ ox, oy = self.origin(current)
171
+ x0, y0 = current
172
+ x2, y2, x3, y3 = self._args
173
+ x2, y2 = x2 + ox, y2 + oy
174
+ x3, y3 = x3 + ox, y3 + oy
175
+ x1, y1 = 2 * x0 - previous[0], 2 * y0 - previous[1]
176
+ self.previous = x2, y2
177
+ vertices = geometry.cubic((x0, y0), (x1, y1), (x2, y2), (x3, y3))
178
+
179
+ return vertices[1:]
180
+
181
+
182
+ # --------------------------------------------------------- SmoothQuadratic ---
183
+ class SmoothQuadratic(Command):
184
+
185
+ def __init__(self, x2=0, y2=0, relative=True):
186
+ self._command = 't' if relative else 'T'
187
+ self._args = [x2, y2]
188
+
189
+ def vertices(self, current, previous):
190
+ ox, oy = self.origin(current)
191
+ x2, y2 = self._args
192
+ x0, y0 = current
193
+ x1, y1 = 2 * x0 - previous[0], 2 * y0 - previous[1]
194
+ x2, y2 = x2 + ox, y2 + oy
195
+ self.previous = x1, y1
196
+ vertices = geometry.quadratic((x0, y0), (x1, y1), (x2, y2))
197
+
198
+ return vertices[1:]
199
+
200
+
201
+ # -------------------------------------------------------------------- Path ---
202
+ class Path(Transformable):
203
+
204
+ def __init__(self, content=None, parent=None):
205
+ Transformable.__init__(self, content, parent)
206
+ self._paths = []
207
+
208
+ if not isinstance(content, str):
209
+ content = content.get("d", "")
210
+
211
+ commands = re.compile(
212
+ r"(?P<command>[MLVHCSQTAZmlvhcsqtaz])"
213
+ r"(?P<points>[+\-0-9.e, \n\t]*)")
214
+
215
+ path = []
216
+ for match in re.finditer(commands, content):
217
+ command = match.group("command")
218
+ points = match.group("points").replace(',', ' ')
219
+ points = [float(v) for v in points.split()]
220
+ relative = command in "mlvhcsqtaz"
221
+ command = command.upper()
222
+
223
+ while len(points) or command == 'Z':
224
+ if command == 'M':
225
+ if len(path):
226
+ self._paths.append(path)
227
+ path = []
228
+ path.append(Move(*points[:2], relative=relative))
229
+ points = points[2:]
230
+ elif command == 'L':
231
+ path.append(Line(*points[:2], relative=relative))
232
+ points = points[2:]
233
+ elif command == 'V':
234
+ path.append(VLine(*points[:1], relative=relative))
235
+ points = points[1:]
236
+ elif command == 'H':
237
+ path.append(HLine(*points[:1], relative=relative))
238
+ points = points[1:]
239
+ elif command == 'C':
240
+ path.append(Cubic(*points[:6], relative=relative))
241
+ points = points[6:]
242
+ elif command == 'S':
243
+ path.append(SmoothCubic(*points[:4], relative=relative))
244
+ points = points[4:]
245
+ elif command == 'Q':
246
+ path.append(Quadratic(*points[:4], relative=relative))
247
+ points = points[4:]
248
+ elif command == 'T':
249
+ path.append(
250
+ SmoothQuadratic(*points[2:], relative=relative))
251
+ points = points[2:]
252
+ elif command == 'A':
253
+ path.append(Arc(*points[:7], relative=relative))
254
+ points = points[7:]
255
+ elif command == 'Z':
256
+ path.append(Close(relative=relative))
257
+ self._paths.append(path)
258
+ path = []
259
+ break
260
+ else:
261
+ raise RuntimeError(
262
+ "Unknown SVG path command(%s)" % command)
263
+
264
+ if len(path):
265
+ self._paths.append(path)
266
+
267
+ def __repr__(self):
268
+ s = ""
269
+ for path in self._paths:
270
+ for item in path:
271
+ s += repr(item)
272
+ return s
273
+
274
+ @property
275
+ def xml(self):
276
+ return self._xml()
277
+
278
+ def _xml(self, prefix=""):
279
+ s = prefix + "<path "
280
+ s += 'id="%s" ' % self._id
281
+ s += self._style.xml
282
+ s += '\n'
283
+ t = ' ' + prefix + ' d="'
284
+ s += t
285
+ prefix = ' ' * len(t)
286
+ first = True
287
+ for i, path in enumerate(self._paths):
288
+ for j, item in enumerate(path):
289
+ if first:
290
+ s += repr(item)
291
+ first = False
292
+ else:
293
+ s += prefix + repr(item)
294
+ if i < len(self._paths) - 1 or j < len(path) - 1:
295
+ s += '\n'
296
+ s += '"/>\n'
297
+ return s
298
+
299
+ @property
300
+ def vertices(self):
301
+ self._vertices = []
302
+ current = 0, 0
303
+ previous = 0, 0
304
+
305
+ for path in self._paths:
306
+ vertices = []
307
+ for command in path:
308
+ V = command.vertices(current, previous)
309
+ previous = command.previous
310
+ vertices.extend(V)
311
+ if len(V) > 0:
312
+ current = V[-1]
313
+ else:
314
+ current = 0, 0
315
+
316
+ closed = False
317
+ if isinstance(command, Close):
318
+ closed = True
319
+ if len(vertices) > 2:
320
+ d = geometry.calc_sq_distance(vertices[-1][0], vertices[-1][1], # noqa
321
+ vertices[0][0], vertices[0][1]) # noqa
322
+ if d < epsilon:
323
+ vertices = vertices[:-1]
324
+
325
+ # Apply transformation
326
+ V = np.ones((len(vertices), 3))
327
+ V[:, :2] = vertices
328
+ V = np.dot(V, self.transform.matrix.T)
329
+ V[:, 2] = 0
330
+ self._vertices.append((V, closed))
331
+
332
+ return self._vertices
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -----------------------------------------------------------------------------
3
+ # Copyright (c) 2014, Nicolas P. Rougier
4
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
5
+ # -----------------------------------------------------------------------------
6
+
7
+
8
+ class Rect(object):
9
+
10
+ def __init__(self, x=0, y=0, width=1, height=1, rx=0, ry=0):
11
+ self.x = x
12
+ self.y = y
13
+ self.width = width
14
+ self.height = height
15
+ self.rx = rx
16
+ self.ry = ry
17
+
18
+ def parse(self, expression):
19
+ """ """
20
+
21
+
22
+ class Line(object):
23
+
24
+ def __init__(self, x1=0, y1=0, x2=0, y2=0):
25
+ self.x1 = x2
26
+ self.y1 = y2
27
+ self.x2 = x2
28
+ self.y2 = y2
29
+
30
+
31
+ class Circle(object):
32
+
33
+ def __init__(self, cx=0, cy=0, r=1):
34
+ self.cx = cx
35
+ self.cy = cy
36
+ self.r = r
37
+
38
+
39
+ class Ellipse(object):
40
+
41
+ def __init__(self, cx=0, cy=0, rx=1, ry=1):
42
+ self.cx = cx
43
+ self.cy = cy
44
+ self.rx = rx
45
+ self.ry = ry
46
+
47
+
48
+ class Polygon(object):
49
+
50
+ def __init__(self, points=[]):
51
+ self.points = points
52
+
53
+
54
+ class Polyline(object):
55
+
56
+ def __init__(self, points=[]):
57
+ self.points = points
@@ -0,0 +1,59 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -----------------------------------------------------------------------------
3
+ # Copyright (c) 2014, Nicolas P. Rougier
4
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
5
+ # -----------------------------------------------------------------------------
6
+
7
+ from . color import Color
8
+ from . number import Number
9
+ from . length import Length
10
+
11
+ _converters = {
12
+ "fill": Color,
13
+ "fill-opacity": Number,
14
+ "stroke": Color,
15
+ "stroke-opacity": Number,
16
+ "opacity": Number,
17
+ "stroke-width": Length,
18
+ # "stroke-miterlimit": Number,
19
+ # "stroke-dasharray": Lengths,
20
+ # "stroke-dashoffset": Length,
21
+ }
22
+
23
+
24
+ class Style(object):
25
+
26
+ def __init__(self):
27
+ self._unset = True
28
+ for key in _converters.keys():
29
+ key_ = key.replace("-", "_")
30
+ self.__setattr__(key_, None)
31
+
32
+ def update(self, content):
33
+ if not content:
34
+ return
35
+
36
+ self._unset = False
37
+ items = content.strip().split(";")
38
+ attributes = dict([item.strip().split(":") for item in items if item])
39
+ for key, value in attributes.items():
40
+ if key in _converters:
41
+ key_ = key.replace("-", "_")
42
+ self.__setattr__(key_, _converters[key](value))
43
+
44
+ @property
45
+ def xml(self):
46
+ return self._xml()
47
+
48
+ def _xml(self, prefix=""):
49
+ if self._unset:
50
+ return ""
51
+
52
+ s = 'style="'
53
+ for key in _converters.keys():
54
+ key_ = key.replace("-", "_")
55
+ value = self.__getattribute__(key_)
56
+ if value is not None:
57
+ s += '%s:%s ' % (key, value)
58
+ s += '"'
59
+ return s
vispy/util/svg/svg.py ADDED
@@ -0,0 +1,40 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -----------------------------------------------------------------------------
3
+ # Copyright (c) 2014, Nicolas P. Rougier. All rights reserved.
4
+ # Distributed under the terms of the new BSD License.
5
+ # -----------------------------------------------------------------------------
6
+
7
+ from . group import Group
8
+ from . viewport import Viewport
9
+
10
+
11
+ class SVG(Group):
12
+
13
+ def __init__(self, content=None, parent=None):
14
+ Group.__init__(self, content, parent)
15
+ self._viewport = Viewport(content)
16
+
17
+ @property
18
+ def viewport(self):
19
+ return self._viewport
20
+
21
+ def __repr__(self):
22
+ s = ""
23
+ for item in self._items:
24
+ s += repr(item) + "\n"
25
+ return s
26
+
27
+ @property
28
+ def xml(self):
29
+ return self._xml()
30
+
31
+ def _xml(self, prefix=""):
32
+ s = "<svg "
33
+ s += 'id="%s" ' % self._id
34
+ s += self._viewport.xml
35
+ s += self._transform.xml
36
+ s += "\n"
37
+ for item in self._items:
38
+ s += item._xml(prefix=prefix + " ") + "\n"
39
+ s += "</svg>\n"
40
+ return s
@@ -0,0 +1,223 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -----------------------------------------------------------------------------
3
+ # Copyright (c) 2014, Nicolas P. Rougier. All rights reserved.
4
+ # Distributed under the terms of the new BSD License.
5
+ # -----------------------------------------------------------------------------
6
+ import re
7
+ import math
8
+ import numpy as np
9
+
10
+ # ------------------------------------------------------------------ Matrix ---
11
+
12
+
13
+ class Matrix(object):
14
+
15
+ def __init__(self, a=1, b=0, c=0, d=1, e=0, f=0):
16
+ self._matrix = np.array([[a, c, e],
17
+ [b, d, f],
18
+ [0, 0, 1]], dtype=float)
19
+
20
+ @property
21
+ def matrix(self):
22
+ return self._matrix
23
+
24
+ def __array__(self, *args):
25
+ return self._matrix
26
+
27
+ def __repr__(self):
28
+ a, c, e = self._matrix[0]
29
+ b, d, f = self._matrix[1]
30
+ return "Matrix(%g,%g,%g,%g,%g,%g)" % (a, b, c, d, e, f)
31
+
32
+
33
+ # ---------------------------------------------------------------- Identity ---
34
+ class Identity(Matrix):
35
+
36
+ def __init__(self):
37
+ Matrix.__init__(self)
38
+ self._matrix[...] = ([[1, 0, 0],
39
+ [0, 1, 0],
40
+ [0, 0, 1]])
41
+
42
+ def __repr__(self):
43
+ return "Identity()"
44
+
45
+
46
+ # --------------------------------------------------------------- Translate ---
47
+ class Translate(Matrix):
48
+ """
49
+ Translation is equivalent to the matrix [1 0 0 1 tx ty], where tx and ty
50
+ are the distances to translate coordinates in X and Y, respectively.
51
+ """
52
+
53
+ def __init__(self, x, y=0):
54
+ Matrix.__init__(self)
55
+ self._x, self._y = x, y
56
+ self._matrix[...] = ([[1, 0, x],
57
+ [0, 1, y],
58
+ [0, 0, 1]])
59
+
60
+ def __repr__(self):
61
+ return "Translate(%g,%g)" % (self._x, self._y)
62
+
63
+
64
+ # ------------------------------------------------------------------- Scale ---
65
+ class Scale(Matrix):
66
+ """
67
+ Scaling is equivalent to the matrix [sx 0 0 sy 0 0]. One unit in the X and
68
+ Y directions in the new coordinate system equals sx and sy units in the
69
+ previous coordinate system, respectively.
70
+ """
71
+
72
+ def __init__(self, x, y=0):
73
+ Matrix.__init__(self)
74
+ self._x = x
75
+ self._y = y or x
76
+ self._matrix[...] = ([[x, 0, 0],
77
+ [0, y, 0],
78
+ [0, 0, 1]])
79
+
80
+ def __repr__(self):
81
+ return "Scale(%g,%g)" % (self._x, self._y)
82
+
83
+
84
+ # ------------------------------------------------------------------- Scale ---
85
+ class Rotate(Matrix):
86
+ """
87
+ Rotation about the origin is equivalent to the matrix [cos(a) sin(a)
88
+ -sin(a) cos(a) 0 0], which has the effect of rotating the coordinate system
89
+ axes by angle a.
90
+ """
91
+
92
+ def __init__(self, angle, x=0, y=0):
93
+ Matrix.__init__(self)
94
+ self._angle = angle
95
+ self._x = x
96
+ self._y = y
97
+
98
+ angle = math.pi * angle / 180.0
99
+ rotate = np.array([[math.cos(angle), -math.sin(angle), 0],
100
+ [math.sin(angle), math.cos(angle), 0],
101
+ [0, 0, 1]], dtype=float)
102
+ forward = np.array([[1, 0, x],
103
+ [0, 1, y],
104
+ [0, 0, 1]], dtype=float)
105
+ inverse = np.array([[1, 0, -x],
106
+ [0, 1, -y],
107
+ [0, 0, 1]], dtype=float)
108
+ self._matrix = np.dot(inverse, np.dot(rotate, forward))
109
+
110
+ def __repr__(self):
111
+ return "Rotate(%g,%g,%g)" % (self._angle, self._x, self._y)
112
+
113
+
114
+ # ------------------------------------------------------------------- SkewX ---
115
+ class SkewX(Matrix):
116
+ """
117
+ A skew transformation along the x-axis is equivalent to the matrix [1 0
118
+ tan(a) 1 0 0], which has the effect of skewing X coordinates by angle a.
119
+ """
120
+
121
+ def __init__(self, angle):
122
+ Matrix.__init__(self)
123
+ self._angle = angle
124
+ angle = math.pi * angle / 180.0
125
+ self._matrix[...] = ([[1, math.tan(angle), 0],
126
+ [0, 1, 0],
127
+ [0, 0, 1]])
128
+
129
+ def __repr__(self):
130
+ return "SkewX(%g)" % (self._angle)
131
+
132
+
133
+ # ------------------------------------------------------------------- SkewY ---
134
+ class SkewY(Matrix):
135
+ """
136
+ A skew transformation along the y-axis is equivalent to the matrix [1
137
+ tan(a) 0 1 0 0], which has the effect of skewing Y coordinates by angle a.
138
+ """
139
+
140
+ def __init__(self, angle):
141
+ Matrix.__init__(self)
142
+ self._angle = angle
143
+ angle = math.pi * angle / 180.0
144
+ self._matrix[...] = ([[1, 0, 0],
145
+ [math.tan(angle), 1, 0],
146
+ [0, 0, 1]])
147
+
148
+ def __repr__(self):
149
+ return "SkewY(%g)" % (self._angle)
150
+
151
+
152
+ # --------------------------------------------------------------- Transform ---
153
+ class Transform(object):
154
+ """
155
+ A Transform is defined as a list of transform definitions, which are
156
+ applied in the order provided. The individual transform definitions are
157
+ separated by whitespace and/or a comma.
158
+ """
159
+
160
+ def __init__(self, content=""):
161
+ self._transforms = []
162
+ if not content:
163
+ return
164
+
165
+ converters = {"matrix": Matrix,
166
+ "scale": Scale,
167
+ "rotate": Rotate,
168
+ "translate": Translate,
169
+ "skewx": SkewX,
170
+ "skewy": SkewY}
171
+ keys = "|".join(converters.keys())
172
+ pattern = r"(?P<name>%s)\s*\((?P<args>[^)]*)\)" % keys
173
+
174
+ for match in re.finditer(pattern, content):
175
+ name = match.group("name").strip()
176
+ args = match.group("args").strip().replace(',', ' ')
177
+ args = [float(value) for value in args.split()]
178
+ transform = converters[name](*args)
179
+ self._transforms.append(transform)
180
+
181
+ def __add__(self, other):
182
+ T = Transform()
183
+ T._transforms.extend(self._transforms)
184
+ T._transforms.extend(other._transforms)
185
+ return T
186
+
187
+ def __radd__(self, other):
188
+ self._transforms.extend(other._transforms)
189
+ return self
190
+
191
+ @property
192
+ def matrix(self):
193
+ M = np.eye(3)
194
+ for transform in self._transforms:
195
+ M = np.dot(M, transform)
196
+ return M
197
+
198
+ def __array__(self, *args):
199
+ return self._matrix
200
+
201
+ def __repr__(self):
202
+ s = ""
203
+ for i in range(len(self._transforms)):
204
+ s += repr(self._transforms[i])
205
+ if i < len(self._transforms) - 1:
206
+ s += ", "
207
+ return s
208
+
209
+ @property
210
+ def xml(self):
211
+ return self._xml()
212
+
213
+ def _xml(self, prefix=""):
214
+
215
+ identity = True
216
+ for transform in self._transforms:
217
+ if not isinstance(transform, Identity):
218
+ identity = False
219
+ break
220
+ if identity:
221
+ return ""
222
+
223
+ return 'transform="%s" ' % repr(self)