sketchily 0.0.2

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.
Files changed (284) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +39 -0
  3. data/Rakefile +40 -0
  4. data/app/helpers/sketchily.rb~ +10 -0
  5. data/app/helpers/sketchily_helper.rb +10 -0
  6. data/app/views/sketchily/_embed.html.erb +28 -0
  7. data/app/views/sketchily/_embed.html.erb~ +28 -0
  8. data/app/views/sketchily/_embed.js.erb +50 -0
  9. data/app/views/sketchily/_embed.js.erb~ +50 -0
  10. data/app/views/sketchily/_sketchily.html.erb +23 -0
  11. data/app/views/sketchily/_sketchily.html.erb~ +23 -0
  12. data/app/views/sketchily/_sketchily_tag.html.erb +21 -0
  13. data/app/views/sketchily/_sketchily_tag.html.erb~ +21 -0
  14. data/app/views/sketchily/_svg_edit_tag.html.erb~ +51 -0
  15. data/app/views/sketchily/svg_edit_tag_.html~ +35 -0
  16. data/lib/sketchily.rb +15 -0
  17. data/lib/sketchily.rb~ +16 -0
  18. data/lib/sketchily/engine.rb +4 -0
  19. data/lib/sketchily/sketchily.rb +28 -0
  20. data/lib/sketchily/sketchily_show.rb~ +13 -0
  21. data/lib/sketchily/sketchily_tag.rb +15 -0
  22. data/lib/sketchily/svg_edit_tag.rb~ +9 -0
  23. data/lib/sketchily/version.rb +3 -0
  24. data/lib/sketchily/version.rb~ +3 -0
  25. data/spec/dummy/README.rdoc +261 -0
  26. data/spec/dummy/Rakefile +7 -0
  27. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  28. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  29. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  30. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  31. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  32. data/spec/dummy/config.ru +4 -0
  33. data/spec/dummy/config/application.rb +59 -0
  34. data/spec/dummy/config/boot.rb +10 -0
  35. data/spec/dummy/config/database.yml +25 -0
  36. data/spec/dummy/config/environment.rb +5 -0
  37. data/spec/dummy/config/environments/development.rb +37 -0
  38. data/spec/dummy/config/environments/production.rb +67 -0
  39. data/spec/dummy/config/environments/test.rb +37 -0
  40. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  41. data/spec/dummy/config/initializers/inflections.rb +15 -0
  42. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  43. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  44. data/spec/dummy/config/initializers/session_store.rb +8 -0
  45. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  46. data/spec/dummy/config/locales/en.yml +5 -0
  47. data/spec/dummy/config/routes.rb +58 -0
  48. data/spec/dummy/public/404.html +26 -0
  49. data/spec/dummy/public/422.html +26 -0
  50. data/spec/dummy/public/500.html +25 -0
  51. data/spec/dummy/public/favicon.ico +0 -0
  52. data/spec/dummy/script/rails +6 -0
  53. data/spec/lib/sketchily_spec.rb +0 -0
  54. data/spec/spec_helper.rb +11 -0
  55. data/vendor/assets/svg-edit-2.6/browser-not-supported.html +27 -0
  56. data/vendor/assets/svg-edit-2.6/browser.js +180 -0
  57. data/vendor/assets/svg-edit-2.6/canvg/canvg.js +2620 -0
  58. data/vendor/assets/svg-edit-2.6/canvg/rgbcolor.js +287 -0
  59. data/vendor/assets/svg-edit-2.6/contextmenu.js +67 -0
  60. data/vendor/assets/svg-edit-2.6/contextmenu/jquery.contextMenu.js +203 -0
  61. data/vendor/assets/svg-edit-2.6/draw.js +528 -0
  62. data/vendor/assets/svg-edit-2.6/embedapi.html +56 -0
  63. data/vendor/assets/svg-edit-2.6/embedapi.js +173 -0
  64. data/vendor/assets/svg-edit-2.6/extensions/closepath_icons.svg +41 -0
  65. data/vendor/assets/svg-edit-2.6/extensions/ext-arrows.js +298 -0
  66. data/vendor/assets/svg-edit-2.6/extensions/ext-closepath.js +92 -0
  67. data/vendor/assets/svg-edit-2.6/extensions/ext-connector.js +587 -0
  68. data/vendor/assets/svg-edit-2.6/extensions/ext-eyedropper.js +109 -0
  69. data/vendor/assets/svg-edit-2.6/extensions/ext-foreignobject.js +277 -0
  70. data/vendor/assets/svg-edit-2.6/extensions/ext-grid.js +184 -0
  71. data/vendor/assets/svg-edit-2.6/extensions/ext-helloworld.js +78 -0
  72. data/vendor/assets/svg-edit-2.6/extensions/ext-imagelib.js +453 -0
  73. data/vendor/assets/svg-edit-2.6/extensions/ext-imagelib.xml +14 -0
  74. data/vendor/assets/svg-edit-2.6/extensions/ext-markers.js +572 -0
  75. data/vendor/assets/svg-edit-2.6/extensions/ext-server_moinsave.js +56 -0
  76. data/vendor/assets/svg-edit-2.6/extensions/ext-server_opensave.js +180 -0
  77. data/vendor/assets/svg-edit-2.6/extensions/ext-shapes.js +387 -0
  78. data/vendor/assets/svg-edit-2.6/extensions/ext-shapes.xml +10 -0
  79. data/vendor/assets/svg-edit-2.6/extensions/eyedropper-icon.xml +34 -0
  80. data/vendor/assets/svg-edit-2.6/extensions/eyedropper.png +0 -0
  81. data/vendor/assets/svg-edit-2.6/extensions/fileopen.php +31 -0
  82. data/vendor/assets/svg-edit-2.6/extensions/filesave.php +44 -0
  83. data/vendor/assets/svg-edit-2.6/extensions/foreignobject-icons.xml +96 -0
  84. data/vendor/assets/svg-edit-2.6/extensions/grid-icon.xml +30 -0
  85. data/vendor/assets/svg-edit-2.6/extensions/helloworld-icon.xml +21 -0
  86. data/vendor/assets/svg-edit-2.6/extensions/imagelib/index.html +64 -0
  87. data/vendor/assets/svg-edit-2.6/extensions/imagelib/smiley.svg +12 -0
  88. data/vendor/assets/svg-edit-2.6/extensions/markers-icons.xml +115 -0
  89. data/vendor/assets/svg-edit-2.6/extensions/shapelib/animal.json +21 -0
  90. data/vendor/assets/svg-edit-2.6/extensions/shapelib/arrow.json +28 -0
  91. data/vendor/assets/svg-edit-2.6/extensions/shapelib/dialog_balloon.json +9 -0
  92. data/vendor/assets/svg-edit-2.6/extensions/shapelib/electronics.json +20 -0
  93. data/vendor/assets/svg-edit-2.6/extensions/shapelib/flowchart.json +25 -0
  94. data/vendor/assets/svg-edit-2.6/extensions/shapelib/game.json +13 -0
  95. data/vendor/assets/svg-edit-2.6/extensions/shapelib/math.json +9 -0
  96. data/vendor/assets/svg-edit-2.6/extensions/shapelib/misc.json +37 -0
  97. data/vendor/assets/svg-edit-2.6/extensions/shapelib/music.json +21 -0
  98. data/vendor/assets/svg-edit-2.6/extensions/shapelib/object.json +19 -0
  99. data/vendor/assets/svg-edit-2.6/extensions/shapelib/raphael.txt +12 -0
  100. data/vendor/assets/svg-edit-2.6/extensions/shapelib/raphael_1.json +67 -0
  101. data/vendor/assets/svg-edit-2.6/extensions/shapelib/raphael_2.json +64 -0
  102. data/vendor/assets/svg-edit-2.6/extensions/shapelib/symbol.json +28 -0
  103. data/vendor/assets/svg-edit-2.6/history.js +601 -0
  104. data/vendor/assets/svg-edit-2.6/images/README.txt +61 -0
  105. data/vendor/assets/svg-edit-2.6/images/align-bottom.png +0 -0
  106. data/vendor/assets/svg-edit-2.6/images/align-bottom.svg +277 -0
  107. data/vendor/assets/svg-edit-2.6/images/align-center.png +0 -0
  108. data/vendor/assets/svg-edit-2.6/images/align-center.svg +252 -0
  109. data/vendor/assets/svg-edit-2.6/images/align-left.png +0 -0
  110. data/vendor/assets/svg-edit-2.6/images/align-left.svg +235 -0
  111. data/vendor/assets/svg-edit-2.6/images/align-middle.png +0 -0
  112. data/vendor/assets/svg-edit-2.6/images/align-middle.svg +250 -0
  113. data/vendor/assets/svg-edit-2.6/images/align-right.png +0 -0
  114. data/vendor/assets/svg-edit-2.6/images/align-right.svg +233 -0
  115. data/vendor/assets/svg-edit-2.6/images/align-top.png +0 -0
  116. data/vendor/assets/svg-edit-2.6/images/align-top.svg +233 -0
  117. data/vendor/assets/svg-edit-2.6/images/bold.png +0 -0
  118. data/vendor/assets/svg-edit-2.6/images/cancel.png +0 -0
  119. data/vendor/assets/svg-edit-2.6/images/circle.png +0 -0
  120. data/vendor/assets/svg-edit-2.6/images/clear.png +0 -0
  121. data/vendor/assets/svg-edit-2.6/images/clone.png +0 -0
  122. data/vendor/assets/svg-edit-2.6/images/conn.svg +29 -0
  123. data/vendor/assets/svg-edit-2.6/images/copy.png +0 -0
  124. data/vendor/assets/svg-edit-2.6/images/cut.png +0 -0
  125. data/vendor/assets/svg-edit-2.6/images/delete.png +0 -0
  126. data/vendor/assets/svg-edit-2.6/images/document-properties.png +0 -0
  127. data/vendor/assets/svg-edit-2.6/images/dropdown.gif +0 -0
  128. data/vendor/assets/svg-edit-2.6/images/ellipse.png +0 -0
  129. data/vendor/assets/svg-edit-2.6/images/eye.png +0 -0
  130. data/vendor/assets/svg-edit-2.6/images/fhpath.png +0 -0
  131. data/vendor/assets/svg-edit-2.6/images/flyouth.png +0 -0
  132. data/vendor/assets/svg-edit-2.6/images/flyup.gif +0 -0
  133. data/vendor/assets/svg-edit-2.6/images/freehand-circle.png +0 -0
  134. data/vendor/assets/svg-edit-2.6/images/freehand-square.png +0 -0
  135. data/vendor/assets/svg-edit-2.6/images/go-down.png +0 -0
  136. data/vendor/assets/svg-edit-2.6/images/go-up.png +0 -0
  137. data/vendor/assets/svg-edit-2.6/images/image.png +0 -0
  138. data/vendor/assets/svg-edit-2.6/images/italic.png +0 -0
  139. data/vendor/assets/svg-edit-2.6/images/line.png +0 -0
  140. data/vendor/assets/svg-edit-2.6/images/link_controls.png +0 -0
  141. data/vendor/assets/svg-edit-2.6/images/logo.png +0 -0
  142. data/vendor/assets/svg-edit-2.6/images/logo.svg +32 -0
  143. data/vendor/assets/svg-edit-2.6/images/move_bottom.png +0 -0
  144. data/vendor/assets/svg-edit-2.6/images/move_top.png +0 -0
  145. data/vendor/assets/svg-edit-2.6/images/node_clone.png +0 -0
  146. data/vendor/assets/svg-edit-2.6/images/node_delete.png +0 -0
  147. data/vendor/assets/svg-edit-2.6/images/none.png +0 -0
  148. data/vendor/assets/svg-edit-2.6/images/open.png +0 -0
  149. data/vendor/assets/svg-edit-2.6/images/paste.png +0 -0
  150. data/vendor/assets/svg-edit-2.6/images/path.png +0 -0
  151. data/vendor/assets/svg-edit-2.6/images/polygon.png +0 -0
  152. data/vendor/assets/svg-edit-2.6/images/polygon.svg +219 -0
  153. data/vendor/assets/svg-edit-2.6/images/rect.png +0 -0
  154. data/vendor/assets/svg-edit-2.6/images/redo.png +0 -0
  155. data/vendor/assets/svg-edit-2.6/images/reorient.png +0 -0
  156. data/vendor/assets/svg-edit-2.6/images/rotate.png +0 -0
  157. data/vendor/assets/svg-edit-2.6/images/save.png +0 -0
  158. data/vendor/assets/svg-edit-2.6/images/select.png +0 -0
  159. data/vendor/assets/svg-edit-2.6/images/select_node.png +0 -0
  160. data/vendor/assets/svg-edit-2.6/images/sep.png +0 -0
  161. data/vendor/assets/svg-edit-2.6/images/shape_group.png +0 -0
  162. data/vendor/assets/svg-edit-2.6/images/shape_ungroup.png +0 -0
  163. data/vendor/assets/svg-edit-2.6/images/source.png +0 -0
  164. data/vendor/assets/svg-edit-2.6/images/spinbtn_updn_big.png +0 -0
  165. data/vendor/assets/svg-edit-2.6/images/square.png +0 -0
  166. data/vendor/assets/svg-edit-2.6/images/svg_edit_icons.svg +1034 -0
  167. data/vendor/assets/svg-edit-2.6/images/svg_edit_icons.svgz +0 -0
  168. data/vendor/assets/svg-edit-2.6/images/text.png +0 -0
  169. data/vendor/assets/svg-edit-2.6/images/text.svg +157 -0
  170. data/vendor/assets/svg-edit-2.6/images/to_path.png +0 -0
  171. data/vendor/assets/svg-edit-2.6/images/undo.png +0 -0
  172. data/vendor/assets/svg-edit-2.6/images/view-refresh.png +0 -0
  173. data/vendor/assets/svg-edit-2.6/images/wave.png +0 -0
  174. data/vendor/assets/svg-edit-2.6/images/wireframe.png +0 -0
  175. data/vendor/assets/svg-edit-2.6/images/zoom.png +0 -0
  176. data/vendor/assets/svg-edit-2.6/jgraduate/LICENSE +202 -0
  177. data/vendor/assets/svg-edit-2.6/jgraduate/README +3 -0
  178. data/vendor/assets/svg-edit-2.6/jgraduate/css/jPicker.css +1 -0
  179. data/vendor/assets/svg-edit-2.6/jgraduate/css/jgraduate.css +351 -0
  180. data/vendor/assets/svg-edit-2.6/jgraduate/images/AlphaBar.png +0 -0
  181. data/vendor/assets/svg-edit-2.6/jgraduate/images/Bars.png +0 -0
  182. data/vendor/assets/svg-edit-2.6/jgraduate/images/Maps.png +0 -0
  183. data/vendor/assets/svg-edit-2.6/jgraduate/images/NoColor.png +0 -0
  184. data/vendor/assets/svg-edit-2.6/jgraduate/images/bar-opacity.png +0 -0
  185. data/vendor/assets/svg-edit-2.6/jgraduate/images/map-opacity.png +0 -0
  186. data/vendor/assets/svg-edit-2.6/jgraduate/images/mappoint.gif +0 -0
  187. data/vendor/assets/svg-edit-2.6/jgraduate/images/mappoint_c.png +0 -0
  188. data/vendor/assets/svg-edit-2.6/jgraduate/images/mappoint_f.png +0 -0
  189. data/vendor/assets/svg-edit-2.6/jgraduate/images/picker.gif +0 -0
  190. data/vendor/assets/svg-edit-2.6/jgraduate/images/preview-opacity.png +0 -0
  191. data/vendor/assets/svg-edit-2.6/jgraduate/images/rangearrows.gif +0 -0
  192. data/vendor/assets/svg-edit-2.6/jgraduate/images/rangearrows2.gif +0 -0
  193. data/vendor/assets/svg-edit-2.6/jgraduate/jpicker.js +2091 -0
  194. data/vendor/assets/svg-edit-2.6/jgraduate/jpicker.min.js +1 -0
  195. data/vendor/assets/svg-edit-2.6/jgraduate/jquery.jgraduate.js +1175 -0
  196. data/vendor/assets/svg-edit-2.6/jgraduate/jquery.jgraduate.min.js +37 -0
  197. data/vendor/assets/svg-edit-2.6/jquery-ui/jquery-ui-1.8.17.custom.min.js +54 -0
  198. data/vendor/assets/svg-edit-2.6/jquery-ui/jquery-ui-1.8.custom.min.js +84 -0
  199. data/vendor/assets/svg-edit-2.6/jquery.js +4 -0
  200. data/vendor/assets/svg-edit-2.6/jquerybbq/jquery.bbq.min.js +18 -0
  201. data/vendor/assets/svg-edit-2.6/js-hotkeys/README.md +45 -0
  202. data/vendor/assets/svg-edit-2.6/js-hotkeys/jquery.hotkeys.min.js +15 -0
  203. data/vendor/assets/svg-edit-2.6/locale/README.txt +17 -0
  204. data/vendor/assets/svg-edit-2.6/locale/lang.af.js +234 -0
  205. data/vendor/assets/svg-edit-2.6/locale/lang.ar.js +234 -0
  206. data/vendor/assets/svg-edit-2.6/locale/lang.az.js +234 -0
  207. data/vendor/assets/svg-edit-2.6/locale/lang.be.js +234 -0
  208. data/vendor/assets/svg-edit-2.6/locale/lang.bg.js +234 -0
  209. data/vendor/assets/svg-edit-2.6/locale/lang.ca.js +234 -0
  210. data/vendor/assets/svg-edit-2.6/locale/lang.cs.js +234 -0
  211. data/vendor/assets/svg-edit-2.6/locale/lang.cy.js +234 -0
  212. data/vendor/assets/svg-edit-2.6/locale/lang.da.js +234 -0
  213. data/vendor/assets/svg-edit-2.6/locale/lang.de.js +234 -0
  214. data/vendor/assets/svg-edit-2.6/locale/lang.el.js +234 -0
  215. data/vendor/assets/svg-edit-2.6/locale/lang.en.js +234 -0
  216. data/vendor/assets/svg-edit-2.6/locale/lang.es.js +234 -0
  217. data/vendor/assets/svg-edit-2.6/locale/lang.et.js +234 -0
  218. data/vendor/assets/svg-edit-2.6/locale/lang.fa.js +234 -0
  219. data/vendor/assets/svg-edit-2.6/locale/lang.fi.js +234 -0
  220. data/vendor/assets/svg-edit-2.6/locale/lang.fr.js +234 -0
  221. data/vendor/assets/svg-edit-2.6/locale/lang.fy.js +234 -0
  222. data/vendor/assets/svg-edit-2.6/locale/lang.ga.js +234 -0
  223. data/vendor/assets/svg-edit-2.6/locale/lang.gl.js +234 -0
  224. data/vendor/assets/svg-edit-2.6/locale/lang.he.js +234 -0
  225. data/vendor/assets/svg-edit-2.6/locale/lang.hi.js +234 -0
  226. data/vendor/assets/svg-edit-2.6/locale/lang.hr.js +234 -0
  227. data/vendor/assets/svg-edit-2.6/locale/lang.hu.js +234 -0
  228. data/vendor/assets/svg-edit-2.6/locale/lang.hy.js +234 -0
  229. data/vendor/assets/svg-edit-2.6/locale/lang.id.js +234 -0
  230. data/vendor/assets/svg-edit-2.6/locale/lang.is.js +234 -0
  231. data/vendor/assets/svg-edit-2.6/locale/lang.it.js +234 -0
  232. data/vendor/assets/svg-edit-2.6/locale/lang.ja.js +234 -0
  233. data/vendor/assets/svg-edit-2.6/locale/lang.ko.js +234 -0
  234. data/vendor/assets/svg-edit-2.6/locale/lang.lt.js +234 -0
  235. data/vendor/assets/svg-edit-2.6/locale/lang.lv.js +234 -0
  236. data/vendor/assets/svg-edit-2.6/locale/lang.mk.js +234 -0
  237. data/vendor/assets/svg-edit-2.6/locale/lang.ms.js +234 -0
  238. data/vendor/assets/svg-edit-2.6/locale/lang.mt.js +234 -0
  239. data/vendor/assets/svg-edit-2.6/locale/lang.nl.js +234 -0
  240. data/vendor/assets/svg-edit-2.6/locale/lang.no.js +234 -0
  241. data/vendor/assets/svg-edit-2.6/locale/lang.pl.js +234 -0
  242. data/vendor/assets/svg-edit-2.6/locale/lang.pt-BR.js +234 -0
  243. data/vendor/assets/svg-edit-2.6/locale/lang.pt-PT.js +234 -0
  244. data/vendor/assets/svg-edit-2.6/locale/lang.ro.js +234 -0
  245. data/vendor/assets/svg-edit-2.6/locale/lang.ru.js +234 -0
  246. data/vendor/assets/svg-edit-2.6/locale/lang.sk.js +234 -0
  247. data/vendor/assets/svg-edit-2.6/locale/lang.sl.js +234 -0
  248. data/vendor/assets/svg-edit-2.6/locale/lang.sq.js +234 -0
  249. data/vendor/assets/svg-edit-2.6/locale/lang.sr.js +234 -0
  250. data/vendor/assets/svg-edit-2.6/locale/lang.sv.js +234 -0
  251. data/vendor/assets/svg-edit-2.6/locale/lang.sw.js +234 -0
  252. data/vendor/assets/svg-edit-2.6/locale/lang.test.js +234 -0
  253. data/vendor/assets/svg-edit-2.6/locale/lang.th.js +234 -0
  254. data/vendor/assets/svg-edit-2.6/locale/lang.tl.js +234 -0
  255. data/vendor/assets/svg-edit-2.6/locale/lang.tr.js +234 -0
  256. data/vendor/assets/svg-edit-2.6/locale/lang.uk.js +234 -0
  257. data/vendor/assets/svg-edit-2.6/locale/lang.vi.js +234 -0
  258. data/vendor/assets/svg-edit-2.6/locale/lang.yi.js +234 -0
  259. data/vendor/assets/svg-edit-2.6/locale/lang.zh-CN.js +234 -0
  260. data/vendor/assets/svg-edit-2.6/locale/lang.zh-HK.js +234 -0
  261. data/vendor/assets/svg-edit-2.6/locale/lang.zh-TW.js +234 -0
  262. data/vendor/assets/svg-edit-2.6/locale/locale.js +320 -0
  263. data/vendor/assets/svg-edit-2.6/math.js +246 -0
  264. data/vendor/assets/svg-edit-2.6/path.js +980 -0
  265. data/vendor/assets/svg-edit-2.6/sanitize.js +273 -0
  266. data/vendor/assets/svg-edit-2.6/select.js +532 -0
  267. data/vendor/assets/svg-edit-2.6/spinbtn/JQuerySpinBtn.css +41 -0
  268. data/vendor/assets/svg-edit-2.6/spinbtn/JQuerySpinBtn.js +266 -0
  269. data/vendor/assets/svg-edit-2.6/spinbtn/JQuerySpinBtn.min.js +7 -0
  270. data/vendor/assets/svg-edit-2.6/spinbtn/spinbtn_updn.png +0 -0
  271. data/vendor/assets/svg-edit-2.6/svg-editor.css +1495 -0
  272. data/vendor/assets/svg-edit-2.6/svg-editor.css~ +1500 -0
  273. data/vendor/assets/svg-edit-2.6/svg-editor.html +788 -0
  274. data/vendor/assets/svg-edit-2.6/svg-editor.html~ +788 -0
  275. data/vendor/assets/svg-edit-2.6/svg-editor.js +4969 -0
  276. data/vendor/assets/svg-edit-2.6/svg-editor.manifest +121 -0
  277. data/vendor/assets/svg-edit-2.6/svgcanvas.js +8775 -0
  278. data/vendor/assets/svg-edit-2.6/svgedit.compiled.js +465 -0
  279. data/vendor/assets/svg-edit-2.6/svgicons/jquery.svgicons.js +486 -0
  280. data/vendor/assets/svg-edit-2.6/svgtransformlist.js +291 -0
  281. data/vendor/assets/svg-edit-2.6/svgutils.js +651 -0
  282. data/vendor/assets/svg-edit-2.6/touch.js +30 -0
  283. data/vendor/assets/svg-edit-2.6/units.js +281 -0
  284. metadata +407 -0
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Package: svedit.math
3
+ *
4
+ * Licensed under the MIT License
5
+ *
6
+ * Copyright(c) 2010 Alexis Deveria
7
+ * Copyright(c) 2010 Jeff Schiller
8
+ */
9
+
10
+ // Dependencies:
11
+ // None.
12
+
13
+ var svgedit = svgedit || {};
14
+
15
+ (function() {
16
+
17
+ if (!svgedit.math) {
18
+ svgedit.math = {};
19
+ }
20
+
21
+ // Constants
22
+ var NEAR_ZERO = 1e-14;
23
+
24
+ // Throw away SVGSVGElement used for creating matrices/transforms.
25
+ var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
26
+
27
+ // Function: svgedit.math.transformPoint
28
+ // A (hopefully) quicker function to transform a point by a matrix
29
+ // (this function avoids any DOM calls and just does the math)
30
+ //
31
+ // Parameters:
32
+ // x - Float representing the x coordinate
33
+ // y - Float representing the y coordinate
34
+ // m - Matrix object to transform the point with
35
+ // Returns a x,y object representing the transformed point
36
+ svgedit.math.transformPoint = function(x, y, m) {
37
+ return { x: m.a * x + m.c * y + m.e, y: m.b * x + m.d * y + m.f};
38
+ };
39
+
40
+
41
+ // Function: svgedit.math.isIdentity
42
+ // Helper function to check if the matrix performs no actual transform
43
+ // (i.e. exists for identity purposes)
44
+ //
45
+ // Parameters:
46
+ // m - The matrix object to check
47
+ //
48
+ // Returns:
49
+ // Boolean indicating whether or not the matrix is 1,0,0,1,0,0
50
+ svgedit.math.isIdentity = function(m) {
51
+ return (m.a === 1 && m.b === 0 && m.c === 0 && m.d === 1 && m.e === 0 && m.f === 0);
52
+ };
53
+
54
+
55
+ // Function: svgedit.math.matrixMultiply
56
+ // This function tries to return a SVGMatrix that is the multiplication m1*m2.
57
+ // We also round to zero when it's near zero
58
+ //
59
+ // Parameters:
60
+ // >= 2 Matrix objects to multiply
61
+ //
62
+ // Returns:
63
+ // The matrix object resulting from the calculation
64
+ svgedit.math.matrixMultiply = function() {
65
+ var args = arguments, i = args.length, m = args[i-1];
66
+
67
+ while(i-- > 1) {
68
+ var m1 = args[i-1];
69
+ m = m1.multiply(m);
70
+ }
71
+ if (Math.abs(m.a) < NEAR_ZERO) m.a = 0;
72
+ if (Math.abs(m.b) < NEAR_ZERO) m.b = 0;
73
+ if (Math.abs(m.c) < NEAR_ZERO) m.c = 0;
74
+ if (Math.abs(m.d) < NEAR_ZERO) m.d = 0;
75
+ if (Math.abs(m.e) < NEAR_ZERO) m.e = 0;
76
+ if (Math.abs(m.f) < NEAR_ZERO) m.f = 0;
77
+
78
+ return m;
79
+ };
80
+
81
+ // Function: svgedit.math.hasMatrixTransform
82
+ // See if the given transformlist includes a non-indentity matrix transform
83
+ //
84
+ // Parameters:
85
+ // tlist - The transformlist to check
86
+ //
87
+ // Returns:
88
+ // Boolean on whether or not a matrix transform was found
89
+ svgedit.math.hasMatrixTransform = function(tlist) {
90
+ if(!tlist) return false;
91
+ var num = tlist.numberOfItems;
92
+ while (num--) {
93
+ var xform = tlist.getItem(num);
94
+ if (xform.type == 1 && !svgedit.math.isIdentity(xform.matrix)) return true;
95
+ }
96
+ return false;
97
+ };
98
+
99
+ // Function: svgedit.math.transformBox
100
+ // Transforms a rectangle based on the given matrix
101
+ //
102
+ // Parameters:
103
+ // l - Float with the box's left coordinate
104
+ // t - Float with the box's top coordinate
105
+ // w - Float with the box width
106
+ // h - Float with the box height
107
+ // m - Matrix object to transform the box by
108
+ //
109
+ // Returns:
110
+ // An object with the following values:
111
+ // * tl - The top left coordinate (x,y object)
112
+ // * tr - The top right coordinate (x,y object)
113
+ // * bl - The bottom left coordinate (x,y object)
114
+ // * br - The bottom right coordinate (x,y object)
115
+ // * aabox - Object with the following values:
116
+ // * Float with the axis-aligned x coordinate
117
+ // * Float with the axis-aligned y coordinate
118
+ // * Float with the axis-aligned width coordinate
119
+ // * Float with the axis-aligned height coordinate
120
+ svgedit.math.transformBox = function(l, t, w, h, m) {
121
+ var topleft = {x:l,y:t},
122
+ topright = {x:(l+w),y:t},
123
+ botright = {x:(l+w),y:(t+h)},
124
+ botleft = {x:l,y:(t+h)};
125
+ var transformPoint = svgedit.math.transformPoint;
126
+ topleft = transformPoint( topleft.x, topleft.y, m );
127
+ var minx = topleft.x,
128
+ maxx = topleft.x,
129
+ miny = topleft.y,
130
+ maxy = topleft.y;
131
+ topright = transformPoint( topright.x, topright.y, m );
132
+ minx = Math.min(minx, topright.x);
133
+ maxx = Math.max(maxx, topright.x);
134
+ miny = Math.min(miny, topright.y);
135
+ maxy = Math.max(maxy, topright.y);
136
+ botleft = transformPoint( botleft.x, botleft.y, m);
137
+ minx = Math.min(minx, botleft.x);
138
+ maxx = Math.max(maxx, botleft.x);
139
+ miny = Math.min(miny, botleft.y);
140
+ maxy = Math.max(maxy, botleft.y);
141
+ botright = transformPoint( botright.x, botright.y, m );
142
+ minx = Math.min(minx, botright.x);
143
+ maxx = Math.max(maxx, botright.x);
144
+ miny = Math.min(miny, botright.y);
145
+ maxy = Math.max(maxy, botright.y);
146
+
147
+ return {tl:topleft, tr:topright, bl:botleft, br:botright,
148
+ aabox: {x:minx, y:miny, width:(maxx-minx), height:(maxy-miny)} };
149
+ };
150
+
151
+ // Function: svgedit.math.transformListToTransform
152
+ // This returns a single matrix Transform for a given Transform List
153
+ // (this is the equivalent of SVGTransformList.consolidate() but unlike
154
+ // that method, this one does not modify the actual SVGTransformList)
155
+ // This function is very liberal with its min,max arguments
156
+ //
157
+ // Parameters:
158
+ // tlist - The transformlist object
159
+ // min - Optional integer indicating start transform position
160
+ // max - Optional integer indicating end transform position
161
+ //
162
+ // Returns:
163
+ // A single matrix transform object
164
+ svgedit.math.transformListToTransform = function(tlist, min, max) {
165
+ if(tlist == null) {
166
+ // Or should tlist = null have been prevented before this?
167
+ return svg.createSVGTransformFromMatrix(svg.createSVGMatrix());
168
+ }
169
+ var min = min == undefined ? 0 : min;
170
+ var max = max == undefined ? (tlist.numberOfItems-1) : max;
171
+ min = parseInt(min);
172
+ max = parseInt(max);
173
+ if (min > max) { var temp = max; max = min; min = temp; }
174
+ var m = svg.createSVGMatrix();
175
+ for (var i = min; i <= max; ++i) {
176
+ // if our indices are out of range, just use a harmless identity matrix
177
+ var mtom = (i >= 0 && i < tlist.numberOfItems ?
178
+ tlist.getItem(i).matrix :
179
+ svg.createSVGMatrix());
180
+ m = svgedit.math.matrixMultiply(m, mtom);
181
+ }
182
+ return svg.createSVGTransformFromMatrix(m);
183
+ };
184
+
185
+
186
+ // Function: svgedit.math.getMatrix
187
+ // Get the matrix object for a given element
188
+ //
189
+ // Parameters:
190
+ // elem - The DOM element to check
191
+ //
192
+ // Returns:
193
+ // The matrix object associated with the element's transformlist
194
+ svgedit.math.getMatrix = function(elem) {
195
+ var tlist = svgedit.transformlist.getTransformList(elem);
196
+ return svgedit.math.transformListToTransform(tlist).matrix;
197
+ };
198
+
199
+
200
+ // Function: svgedit.math.snapToAngle
201
+ // Returns a 45 degree angle coordinate associated with the two given
202
+ // coordinates
203
+ //
204
+ // Parameters:
205
+ // x1 - First coordinate's x value
206
+ // x2 - Second coordinate's x value
207
+ // y1 - First coordinate's y value
208
+ // y2 - Second coordinate's y value
209
+ //
210
+ // Returns:
211
+ // Object with the following values:
212
+ // x - The angle-snapped x value
213
+ // y - The angle-snapped y value
214
+ // snapangle - The angle at which to snap
215
+ svgedit.math.snapToAngle = function(x1,y1,x2,y2) {
216
+ var snap = Math.PI/4; // 45 degrees
217
+ var dx = x2 - x1;
218
+ var dy = y2 - y1;
219
+ var angle = Math.atan2(dy,dx);
220
+ var dist = Math.sqrt(dx * dx + dy * dy);
221
+ var snapangle= Math.round(angle/snap)*snap;
222
+ var x = x1 + dist*Math.cos(snapangle);
223
+ var y = y1 + dist*Math.sin(snapangle);
224
+ //console.log(x1,y1,x2,y2,x,y,angle)
225
+ return {x:x, y:y, a:snapangle};
226
+ };
227
+
228
+
229
+ // Function: rectsIntersect
230
+ // Check if two rectangles (BBoxes objects) intersect each other
231
+ //
232
+ // Paramaters:
233
+ // r1 - The first BBox-like object
234
+ // r2 - The second BBox-like object
235
+ //
236
+ // Returns:
237
+ // Boolean that's true if rectangles intersect
238
+ svgedit.math.rectsIntersect = function(r1, r2) {
239
+ return r2.x < (r1.x+r1.width) &&
240
+ (r2.x+r2.width) > r1.x &&
241
+ r2.y < (r1.y+r1.height) &&
242
+ (r2.y+r2.height) > r1.y;
243
+ };
244
+
245
+
246
+ })();
@@ -0,0 +1,980 @@
1
+ /**
2
+ * Package: svgedit.path
3
+ *
4
+ * Licensed under the MIT License
5
+ *
6
+ * Copyright(c) 2011 Alexis Deveria
7
+ * Copyright(c) 2011 Jeff Schiller
8
+ */
9
+
10
+ // Dependencies:
11
+ // 1) jQuery
12
+ // 2) browser.js
13
+ // 3) math.js
14
+ // 4) svgutils.js
15
+
16
+ var svgedit = svgedit || {};
17
+
18
+ (function() {
19
+
20
+ if (!svgedit.path) {
21
+ svgedit.path = {};
22
+ }
23
+
24
+ var svgns = "http://www.w3.org/2000/svg";
25
+
26
+ var uiStrings = {
27
+ "pathNodeTooltip": "Drag node to move it. Double-click node to change segment type",
28
+ "pathCtrlPtTooltip": "Drag control point to adjust curve properties"
29
+ };
30
+
31
+ var segData = {
32
+ 2: ['x','y'],
33
+ 4: ['x','y'],
34
+ 6: ['x','y','x1','y1','x2','y2'],
35
+ 8: ['x','y','x1','y1'],
36
+ 10: ['x','y','r1','r2','angle','largeArcFlag','sweepFlag'],
37
+ 12: ['x'],
38
+ 14: ['y'],
39
+ 16: ['x','y','x2','y2'],
40
+ 18: ['x','y']
41
+ };
42
+
43
+ var pathFuncs = [];
44
+
45
+ var link_control_pts = true;
46
+
47
+ // Stores references to paths via IDs.
48
+ // TODO: Make this cross-document happy.
49
+ var pathData = {};
50
+
51
+ svgedit.path.setLinkControlPoints = function(lcp) {
52
+ link_control_pts = lcp;
53
+ };
54
+
55
+ svgedit.path.path = null;
56
+
57
+ var editorContext_ = null;
58
+
59
+ svgedit.path.init = function(editorContext) {
60
+ editorContext_ = editorContext;
61
+
62
+ pathFuncs = [0,'ClosePath'];
63
+ var pathFuncsStrs = ['Moveto', 'Lineto', 'CurvetoCubic', 'CurvetoQuadratic', 'Arc',
64
+ 'LinetoHorizontal', 'LinetoVertical','CurvetoCubicSmooth','CurvetoQuadraticSmooth'];
65
+ $.each(pathFuncsStrs, function(i,s) {
66
+ pathFuncs.push(s+'Abs');
67
+ pathFuncs.push(s+'Rel');
68
+ });
69
+ };
70
+
71
+ svgedit.path.insertItemBefore = function(elem, newseg, index) {
72
+ // Support insertItemBefore on paths for FF2
73
+ var list = elem.pathSegList;
74
+
75
+ if(svgedit.browser.supportsPathInsertItemBefore()) {
76
+ list.insertItemBefore(newseg, index);
77
+ return;
78
+ }
79
+ var len = list.numberOfItems;
80
+ var arr = [];
81
+ for(var i=0; i<len; i++) {
82
+ var cur_seg = list.getItem(i);
83
+ arr.push(cur_seg)
84
+ }
85
+ list.clear();
86
+ for(var i=0; i<len; i++) {
87
+ if(i == index) { //index+1
88
+ list.appendItem(newseg);
89
+ }
90
+ list.appendItem(arr[i]);
91
+ }
92
+ };
93
+
94
+ // TODO: See if this should just live in replacePathSeg
95
+ svgedit.path.ptObjToArr = function(type, seg_item) {
96
+ var arr = segData[type], len = arr.length;
97
+ var out = Array(len);
98
+ for(var i=0; i<len; i++) {
99
+ out[i] = seg_item[arr[i]];
100
+ }
101
+ return out;
102
+ };
103
+
104
+ svgedit.path.getGripPt = function(seg, alt_pt) {
105
+ var out = {
106
+ x: alt_pt? alt_pt.x : seg.item.x,
107
+ y: alt_pt? alt_pt.y : seg.item.y
108
+ }, path = seg.path;
109
+
110
+ if(path.matrix) {
111
+ var pt = svgedit.math.transformPoint(out.x, out.y, path.matrix);
112
+ out = pt;
113
+ }
114
+
115
+ out.x *= editorContext_.getCurrentZoom();
116
+ out.y *= editorContext_.getCurrentZoom();
117
+
118
+ return out;
119
+ };
120
+
121
+ svgedit.path.getPointFromGrip = function(pt, path) {
122
+ var out = {
123
+ x: pt.x,
124
+ y: pt.y
125
+ }
126
+
127
+ if(path.matrix) {
128
+ var pt = svgedit.math.transformPoint(out.x, out.y, path.imatrix);
129
+ out.x = pt.x;
130
+ out.y = pt.y;
131
+ }
132
+
133
+ out.x /= editorContext_.getCurrentZoom();
134
+ out.y /= editorContext_.getCurrentZoom();
135
+
136
+ return out;
137
+ };
138
+
139
+ svgedit.path.addPointGrip = function(index, x, y) {
140
+ // create the container of all the point grips
141
+ var pointGripContainer = svgedit.path.getGripContainer();
142
+
143
+ var pointGrip = svgedit.utilities.getElem("pathpointgrip_"+index);
144
+ // create it
145
+ if (!pointGrip) {
146
+ pointGrip = document.createElementNS(svgns, "circle");
147
+ svgedit.utilities.assignAttributes(pointGrip, {
148
+ 'id': "pathpointgrip_" + index,
149
+ 'display': "none",
150
+ 'r': 4,
151
+ 'fill': "#0FF",
152
+ 'stroke': "#00F",
153
+ 'stroke-width': 2,
154
+ 'cursor': 'move',
155
+ 'style': 'pointer-events:all',
156
+ 'xlink:title': uiStrings.pathNodeTooltip
157
+ });
158
+ pointGrip = pointGripContainer.appendChild(pointGrip);
159
+
160
+ var grip = $('#pathpointgrip_'+index);
161
+ grip.dblclick(function() {
162
+ if(svgedit.path.path) svgedit.path.path.setSegType();
163
+ });
164
+ }
165
+ if(x && y) {
166
+ // set up the point grip element and display it
167
+ svgedit.utilities.assignAttributes(pointGrip, {
168
+ 'cx': x,
169
+ 'cy': y,
170
+ 'display': "inline"
171
+ });
172
+ }
173
+ return pointGrip;
174
+ };
175
+
176
+ svgedit.path.getGripContainer = function() {
177
+ var c = svgedit.utilities.getElem("pathpointgrip_container");
178
+ if (!c) {
179
+ var parent = svgedit.utilities.getElem("selectorParentGroup");
180
+ c = parent.appendChild(document.createElementNS(svgns, "g"));
181
+ c.id = "pathpointgrip_container";
182
+ }
183
+ return c;
184
+ };
185
+
186
+ svgedit.path.addCtrlGrip = function(id) {
187
+ var pointGrip = svgedit.utilities.getElem("ctrlpointgrip_"+id);
188
+ if(pointGrip) return pointGrip;
189
+
190
+ pointGrip = document.createElementNS(svgns, "circle");
191
+ svgedit.utilities.assignAttributes(pointGrip, {
192
+ 'id': "ctrlpointgrip_" + id,
193
+ 'display': "none",
194
+ 'r': 4,
195
+ 'fill': "#0FF",
196
+ 'stroke': "#55F",
197
+ 'stroke-width': 1,
198
+ 'cursor': 'move',
199
+ 'style': 'pointer-events:all',
200
+ 'xlink:title': uiStrings.pathCtrlPtTooltip
201
+ });
202
+ svgedit.path.getGripContainer().appendChild(pointGrip);
203
+ return pointGrip;
204
+ };
205
+
206
+ svgedit.path.getCtrlLine = function(id) {
207
+ var ctrlLine = svgedit.utilities.getElem("ctrlLine_"+id);
208
+ if(ctrlLine) return ctrlLine;
209
+
210
+ ctrlLine = document.createElementNS(svgns, "line");
211
+ svgedit.utilities.assignAttributes(ctrlLine, {
212
+ 'id': "ctrlLine_"+id,
213
+ 'stroke': "#555",
214
+ 'stroke-width': 1,
215
+ "style": "pointer-events:none"
216
+ });
217
+ svgedit.path.getGripContainer().appendChild(ctrlLine);
218
+ return ctrlLine;
219
+ };
220
+
221
+ svgedit.path.getPointGrip = function(seg, update) {
222
+ var index = seg.index;
223
+ var pointGrip = svgedit.path.addPointGrip(index);
224
+
225
+ if(update) {
226
+ var pt = svgedit.path.getGripPt(seg);
227
+ svgedit.utilities.assignAttributes(pointGrip, {
228
+ 'cx': pt.x,
229
+ 'cy': pt.y,
230
+ 'display': "inline"
231
+ });
232
+ }
233
+
234
+ return pointGrip;
235
+ };
236
+
237
+ svgedit.path.getControlPoints = function(seg) {
238
+ var item = seg.item;
239
+ var index = seg.index;
240
+ if(!("x1" in item) || !("x2" in item)) return null;
241
+ var cpt = {};
242
+ var pointGripContainer = svgedit.path.getGripContainer();
243
+
244
+ // Note that this is intentionally not seg.prev.item
245
+ var prev = svgedit.path.path.segs[index-1].item;
246
+
247
+ var seg_items = [prev, item];
248
+
249
+ for(var i=1; i<3; i++) {
250
+ var id = index + 'c' + i;
251
+
252
+ var ctrlLine = cpt['c' + i + '_line'] = svgedit.path.getCtrlLine(id);
253
+
254
+ var pt = svgedit.path.getGripPt(seg, {x:item['x' + i], y:item['y' + i]});
255
+ var gpt = svgedit.path.getGripPt(seg, {x:seg_items[i-1].x, y:seg_items[i-1].y});
256
+
257
+ svgedit.utilities.assignAttributes(ctrlLine, {
258
+ 'x1': pt.x,
259
+ 'y1': pt.y,
260
+ 'x2': gpt.x,
261
+ 'y2': gpt.y,
262
+ 'display': "inline"
263
+ });
264
+
265
+ cpt['c' + i + '_line'] = ctrlLine;
266
+
267
+ // create it
268
+ pointGrip = cpt['c' + i] = svgedit.path.addCtrlGrip(id);
269
+
270
+ svgedit.utilities.assignAttributes(pointGrip, {
271
+ 'cx': pt.x,
272
+ 'cy': pt.y,
273
+ 'display': "inline"
274
+ });
275
+ cpt['c' + i] = pointGrip;
276
+ }
277
+ return cpt;
278
+ };
279
+
280
+ // This replaces the segment at the given index. Type is given as number.
281
+ svgedit.path.replacePathSeg = function(type, index, pts, elem) {
282
+ var path = elem || svgedit.path.path.elem;
283
+ var func = 'createSVGPathSeg' + pathFuncs[type];
284
+ var seg = path[func].apply(path, pts);
285
+
286
+ if(svgedit.browser.supportsPathReplaceItem()) {
287
+ path.pathSegList.replaceItem(seg, index);
288
+ } else {
289
+ var segList = path.pathSegList;
290
+ var len = segList.numberOfItems;
291
+ var arr = [];
292
+ for(var i=0; i<len; i++) {
293
+ var cur_seg = segList.getItem(i);
294
+ arr.push(cur_seg)
295
+ }
296
+ segList.clear();
297
+ for(var i=0; i<len; i++) {
298
+ if(i == index) {
299
+ segList.appendItem(seg);
300
+ } else {
301
+ segList.appendItem(arr[i]);
302
+ }
303
+ }
304
+ }
305
+ };
306
+
307
+ svgedit.path.getSegSelector = function(seg, update) {
308
+ var index = seg.index;
309
+ var segLine = svgedit.utilities.getElem("segline_" + index);
310
+ if(!segLine) {
311
+ var pointGripContainer = svgedit.path.getGripContainer();
312
+ // create segline
313
+ segLine = document.createElementNS(svgns, "path");
314
+ svgedit.utilities.assignAttributes(segLine, {
315
+ 'id': "segline_" + index,
316
+ 'display': 'none',
317
+ 'fill': "none",
318
+ 'stroke': "#0FF",
319
+ 'stroke-width': 2,
320
+ 'style':'pointer-events:none',
321
+ 'd': 'M0,0 0,0'
322
+ });
323
+ pointGripContainer.appendChild(segLine);
324
+ }
325
+
326
+ if(update) {
327
+ var prev = seg.prev;
328
+ if(!prev) {
329
+ segLine.setAttribute("display", "none");
330
+ return segLine;
331
+ }
332
+
333
+ var pt = svgedit.path.getGripPt(prev);
334
+ // Set start point
335
+ svgedit.path.replacePathSeg(2, 0, [pt.x, pt.y], segLine);
336
+
337
+ var pts = svgedit.path.ptObjToArr(seg.type, seg.item, true);
338
+ for(var i=0; i < pts.length; i+=2) {
339
+ var pt = svgedit.path.getGripPt(seg, {x:pts[i], y:pts[i+1]});
340
+ pts[i] = pt.x;
341
+ pts[i+1] = pt.y;
342
+ }
343
+
344
+ svgedit.path.replacePathSeg(seg.type, 1, pts, segLine);
345
+ }
346
+ return segLine;
347
+ };
348
+
349
+ // Function: smoothControlPoints
350
+ // Takes three points and creates a smoother line based on them
351
+ //
352
+ // Parameters:
353
+ // ct1 - Object with x and y values (first control point)
354
+ // ct2 - Object with x and y values (second control point)
355
+ // pt - Object with x and y values (third point)
356
+ //
357
+ // Returns:
358
+ // Array of two "smoothed" point objects
359
+ svgedit.path.smoothControlPoints = this.smoothControlPoints = function(ct1, ct2, pt) {
360
+ // each point must not be the origin
361
+ var x1 = ct1.x - pt.x,
362
+ y1 = ct1.y - pt.y,
363
+ x2 = ct2.x - pt.x,
364
+ y2 = ct2.y - pt.y;
365
+
366
+ if ( (x1 != 0 || y1 != 0) && (x2 != 0 || y2 != 0) ) {
367
+ var anglea = Math.atan2(y1,x1),
368
+ angleb = Math.atan2(y2,x2),
369
+ r1 = Math.sqrt(x1*x1+y1*y1),
370
+ r2 = Math.sqrt(x2*x2+y2*y2),
371
+ nct1 = editorContext_.getSVGRoot().createSVGPoint(),
372
+ nct2 = editorContext_.getSVGRoot().createSVGPoint();
373
+ if (anglea < 0) { anglea += 2*Math.PI; }
374
+ if (angleb < 0) { angleb += 2*Math.PI; }
375
+
376
+ var angleBetween = Math.abs(anglea - angleb),
377
+ angleDiff = Math.abs(Math.PI - angleBetween)/2;
378
+
379
+ var new_anglea, new_angleb;
380
+ if (anglea - angleb > 0) {
381
+ new_anglea = angleBetween < Math.PI ? (anglea + angleDiff) : (anglea - angleDiff);
382
+ new_angleb = angleBetween < Math.PI ? (angleb - angleDiff) : (angleb + angleDiff);
383
+ }
384
+ else {
385
+ new_anglea = angleBetween < Math.PI ? (anglea - angleDiff) : (anglea + angleDiff);
386
+ new_angleb = angleBetween < Math.PI ? (angleb + angleDiff) : (angleb - angleDiff);
387
+ }
388
+
389
+ // rotate the points
390
+ nct1.x = r1 * Math.cos(new_anglea) + pt.x;
391
+ nct1.y = r1 * Math.sin(new_anglea) + pt.y;
392
+ nct2.x = r2 * Math.cos(new_angleb) + pt.x;
393
+ nct2.y = r2 * Math.sin(new_angleb) + pt.y;
394
+
395
+ return [nct1, nct2];
396
+ }
397
+ return undefined;
398
+ };
399
+
400
+ svgedit.path.Segment = function(index, item) {
401
+ this.selected = false;
402
+ this.index = index;
403
+ this.item = item;
404
+ this.type = item.pathSegType;
405
+
406
+ this.ctrlpts = [];
407
+ this.ptgrip = null;
408
+ this.segsel = null;
409
+ };
410
+
411
+ svgedit.path.Segment.prototype.showCtrlPts = function(y) {
412
+ for (var i in this.ctrlpts) {
413
+ this.ctrlpts[i].setAttribute("display", y ? "inline" : "none");
414
+ }
415
+ };
416
+
417
+ svgedit.path.Segment.prototype.selectCtrls = function(y) {
418
+ $('#ctrlpointgrip_' + this.index + 'c1, #ctrlpointgrip_' + this.index + 'c2').
419
+ attr('fill', y ? '#0FF' : '#EEE');
420
+ };
421
+
422
+ svgedit.path.Segment.prototype.show = function(y) {
423
+ if(this.ptgrip) {
424
+ this.ptgrip.setAttribute("display", y ? "inline" : "none");
425
+ this.segsel.setAttribute("display", y ? "inline" : "none");
426
+ // Show/hide all control points if available
427
+ this.showCtrlPts(y);
428
+ }
429
+ };
430
+
431
+ svgedit.path.Segment.prototype.select = function(y) {
432
+ if(this.ptgrip) {
433
+ this.ptgrip.setAttribute("stroke", y ? "#0FF" : "#00F");
434
+ this.segsel.setAttribute("display", y ? "inline" : "none");
435
+ if(this.ctrlpts) {
436
+ this.selectCtrls(y);
437
+ }
438
+ this.selected = y;
439
+ }
440
+ };
441
+
442
+ svgedit.path.Segment.prototype.addGrip = function() {
443
+ this.ptgrip = svgedit.path.getPointGrip(this, true);
444
+ this.ctrlpts = svgedit.path.getControlPoints(this, true);
445
+ this.segsel = svgedit.path.getSegSelector(this, true);
446
+ };
447
+
448
+ svgedit.path.Segment.prototype.update = function(full) {
449
+ if(this.ptgrip) {
450
+ var pt = svgedit.path.getGripPt(this);
451
+ svgedit.utilities.assignAttributes(this.ptgrip, {
452
+ 'cx': pt.x,
453
+ 'cy': pt.y
454
+ });
455
+
456
+ svgedit.path.getSegSelector(this, true);
457
+
458
+ if(this.ctrlpts) {
459
+ if(full) {
460
+ this.item = svgedit.path.path.elem.pathSegList.getItem(this.index);
461
+ this.type = this.item.pathSegType;
462
+ }
463
+ svgedit.path.getControlPoints(this);
464
+ }
465
+ // this.segsel.setAttribute("display", y?"inline":"none");
466
+ }
467
+ };
468
+
469
+ svgedit.path.Segment.prototype.move = function(dx, dy) {
470
+ var item = this.item;
471
+
472
+ if(this.ctrlpts) {
473
+ var cur_pts = [item.x += dx, item.y += dy,
474
+ item.x1, item.y1, item.x2 += dx, item.y2 += dy];
475
+ } else {
476
+ var cur_pts = [item.x += dx, item.y += dy];
477
+ }
478
+ svgedit.path.replacePathSeg(this.type, this.index, cur_pts);
479
+
480
+ if(this.next && this.next.ctrlpts) {
481
+ var next = this.next.item;
482
+ var next_pts = [next.x, next.y,
483
+ next.x1 += dx, next.y1 += dy, next.x2, next.y2];
484
+ svgedit.path.replacePathSeg(this.next.type, this.next.index, next_pts);
485
+ }
486
+
487
+ if(this.mate) {
488
+ // The last point of a closed subpath has a "mate",
489
+ // which is the "M" segment of the subpath
490
+ var item = this.mate.item;
491
+ var pts = [item.x += dx, item.y += dy];
492
+ svgedit.path.replacePathSeg(this.mate.type, this.mate.index, pts);
493
+ // Has no grip, so does not need "updating"?
494
+ }
495
+
496
+ this.update(true);
497
+ if(this.next) this.next.update(true);
498
+ };
499
+
500
+ svgedit.path.Segment.prototype.setLinked = function(num) {
501
+ var seg, anum, pt;
502
+ if (num == 2) {
503
+ anum = 1;
504
+ seg = this.next;
505
+ if(!seg) return;
506
+ pt = this.item;
507
+ } else {
508
+ anum = 2;
509
+ seg = this.prev;
510
+ if(!seg) return;
511
+ pt = seg.item;
512
+ }
513
+
514
+ var item = seg.item;
515
+
516
+ item['x' + anum] = pt.x + (pt.x - this.item['x' + num]);
517
+ item['y' + anum] = pt.y + (pt.y - this.item['y' + num]);
518
+
519
+ var pts = [item.x, item.y,
520
+ item.x1, item.y1,
521
+ item.x2, item.y2];
522
+
523
+ svgedit.path.replacePathSeg(seg.type, seg.index, pts);
524
+ seg.update(true);
525
+ };
526
+
527
+ svgedit.path.Segment.prototype.moveCtrl = function(num, dx, dy) {
528
+ var item = this.item;
529
+
530
+ item['x' + num] += dx;
531
+ item['y' + num] += dy;
532
+
533
+ var pts = [item.x,item.y,
534
+ item.x1,item.y1, item.x2,item.y2];
535
+
536
+ svgedit.path.replacePathSeg(this.type, this.index, pts);
537
+ this.update(true);
538
+ };
539
+
540
+ svgedit.path.Segment.prototype.setType = function(new_type, pts) {
541
+ svgedit.path.replacePathSeg(new_type, this.index, pts);
542
+ this.type = new_type;
543
+ this.item = svgedit.path.path.elem.pathSegList.getItem(this.index);
544
+ this.showCtrlPts(new_type === 6);
545
+ this.ctrlpts = svgedit.path.getControlPoints(this);
546
+ this.update(true);
547
+ };
548
+
549
+ svgedit.path.Path = function(elem) {
550
+ if(!elem || elem.tagName !== "path") {
551
+ throw "svgedit.path.Path constructed without a <path> element";
552
+ }
553
+
554
+ this.elem = elem;
555
+ this.segs = [];
556
+ this.selected_pts = [];
557
+ svgedit.path.path = this;
558
+
559
+ this.init();
560
+ };
561
+
562
+ // Reset path data
563
+ svgedit.path.Path.prototype.init = function() {
564
+ // Hide all grips, etc
565
+ $(svgedit.path.getGripContainer()).find("*").attr("display", "none");
566
+ var segList = this.elem.pathSegList;
567
+ var len = segList.numberOfItems;
568
+ this.segs = [];
569
+ this.selected_pts = [];
570
+ this.first_seg = null;
571
+
572
+ // Set up segs array
573
+ for(var i=0; i < len; i++) {
574
+ var item = segList.getItem(i);
575
+ var segment = new svgedit.path.Segment(i, item);
576
+ segment.path = this;
577
+ this.segs.push(segment);
578
+ }
579
+
580
+ var segs = this.segs;
581
+ var start_i = null;
582
+
583
+ for(var i=0; i < len; i++) {
584
+ var seg = segs[i];
585
+ var next_seg = (i+1) >= len ? null : segs[i+1];
586
+ var prev_seg = (i-1) < 0 ? null : segs[i-1];
587
+
588
+ if(seg.type === 2) {
589
+ if(prev_seg && prev_seg.type !== 1) {
590
+ // New sub-path, last one is open,
591
+ // so add a grip to last sub-path's first point
592
+ var start_seg = segs[start_i];
593
+ start_seg.next = segs[start_i+1];
594
+ start_seg.next.prev = start_seg;
595
+ start_seg.addGrip();
596
+ }
597
+ // Remember that this is a starter seg
598
+ start_i = i;
599
+ } else if(next_seg && next_seg.type === 1) {
600
+ // This is the last real segment of a closed sub-path
601
+ // Next is first seg after "M"
602
+ seg.next = segs[start_i+1];
603
+
604
+ // First seg after "M"'s prev is this
605
+ seg.next.prev = seg;
606
+ seg.mate = segs[start_i];
607
+ seg.addGrip();
608
+ if(this.first_seg == null) {
609
+ this.first_seg = seg;
610
+ }
611
+ } else if(!next_seg) {
612
+ if(seg.type !== 1) {
613
+ // Last seg, doesn't close so add a grip
614
+ // to last sub-path's first point
615
+ var start_seg = segs[start_i];
616
+ start_seg.next = segs[start_i+1];
617
+ start_seg.next.prev = start_seg;
618
+ start_seg.addGrip();
619
+ seg.addGrip();
620
+
621
+ if(!this.first_seg) {
622
+ // Open path, so set first as real first and add grip
623
+ this.first_seg = segs[start_i];
624
+ }
625
+ }
626
+ } else if(seg.type !== 1){
627
+ // Regular segment, so add grip and its "next"
628
+ seg.addGrip();
629
+
630
+ // Don't set its "next" if it's an "M"
631
+ if(next_seg && next_seg.type !== 2) {
632
+ seg.next = next_seg;
633
+ seg.next.prev = seg;
634
+ }
635
+ }
636
+ }
637
+ return this;
638
+ };
639
+
640
+ svgedit.path.Path.prototype.eachSeg = function(fn) {
641
+ var len = this.segs.length
642
+ for(var i=0; i < len; i++) {
643
+ var ret = fn.call(this.segs[i], i);
644
+ if(ret === false) break;
645
+ }
646
+ };
647
+
648
+ svgedit.path.Path.prototype.addSeg = function(index) {
649
+ // Adds a new segment
650
+ var seg = this.segs[index];
651
+ if(!seg.prev) return;
652
+
653
+ var prev = seg.prev;
654
+ var newseg;
655
+ switch(seg.item.pathSegType) {
656
+ case 4:
657
+ var new_x = (seg.item.x + prev.item.x) / 2;
658
+ var new_y = (seg.item.y + prev.item.y) / 2;
659
+ newseg = this.elem.createSVGPathSegLinetoAbs(new_x, new_y);
660
+ break;
661
+ case 6: //make it a curved segment to preserve the shape (WRS)
662
+ // http://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm#Geometric_interpretation
663
+ var p0_x = (prev.item.x + seg.item.x1)/2;
664
+ var p1_x = (seg.item.x1 + seg.item.x2)/2;
665
+ var p2_x = (seg.item.x2 + seg.item.x)/2;
666
+ var p01_x = (p0_x + p1_x)/2;
667
+ var p12_x = (p1_x + p2_x)/2;
668
+ var new_x = (p01_x + p12_x)/2;
669
+ var p0_y = (prev.item.y + seg.item.y1)/2;
670
+ var p1_y = (seg.item.y1 + seg.item.y2)/2;
671
+ var p2_y = (seg.item.y2 + seg.item.y)/2;
672
+ var p01_y = (p0_y + p1_y)/2;
673
+ var p12_y = (p1_y + p2_y)/2;
674
+ var new_y = (p01_y + p12_y)/2;
675
+ newseg = this.elem.createSVGPathSegCurvetoCubicAbs(new_x,new_y, p0_x,p0_y, p01_x,p01_y);
676
+ var pts = [seg.item.x,seg.item.y,p12_x,p12_y,p2_x,p2_y];
677
+ svgedit.path.replacePathSeg(seg.type,index,pts);
678
+ break;
679
+ }
680
+
681
+ svgedit.path.insertItemBefore(this.elem, newseg, index);
682
+ };
683
+
684
+ svgedit.path.Path.prototype.deleteSeg = function(index) {
685
+ var seg = this.segs[index];
686
+ var list = this.elem.pathSegList;
687
+
688
+ seg.show(false);
689
+ var next = seg.next;
690
+ if(seg.mate) {
691
+ // Make the next point be the "M" point
692
+ var pt = [next.item.x, next.item.y];
693
+ svgedit.path.replacePathSeg(2, next.index, pt);
694
+
695
+ // Reposition last node
696
+ svgedit.path.replacePathSeg(4, seg.index, pt);
697
+
698
+ list.removeItem(seg.mate.index);
699
+ } else if(!seg.prev) {
700
+ // First node of open path, make next point the M
701
+ var item = seg.item;
702
+ var pt = [next.item.x, next.item.y];
703
+ svgedit.path.replacePathSeg(2, seg.next.index, pt);
704
+ list.removeItem(index);
705
+
706
+ } else {
707
+ list.removeItem(index);
708
+ }
709
+ };
710
+
711
+ svgedit.path.Path.prototype.subpathIsClosed = function(index) {
712
+ var closed = false;
713
+ // Check if subpath is already open
714
+ svgedit.path.path.eachSeg(function(i) {
715
+ if(i <= index) return true;
716
+ if(this.type === 2) {
717
+ // Found M first, so open
718
+ return false;
719
+ } else if(this.type === 1) {
720
+ // Found Z first, so closed
721
+ closed = true;
722
+ return false;
723
+ }
724
+ });
725
+
726
+ return closed;
727
+ };
728
+
729
+ svgedit.path.Path.prototype.removePtFromSelection = function(index) {
730
+ var pos = this.selected_pts.indexOf(index);
731
+ if(pos == -1) {
732
+ return;
733
+ }
734
+ this.segs[index].select(false);
735
+ this.selected_pts.splice(pos, 1);
736
+ };
737
+
738
+ svgedit.path.Path.prototype.clearSelection = function() {
739
+ this.eachSeg(function(i) {
740
+ // 'this' is the segment here
741
+ this.select(false);
742
+ });
743
+ this.selected_pts = [];
744
+ };
745
+
746
+ svgedit.path.Path.prototype.storeD = function() {
747
+ this.last_d = this.elem.getAttribute('d');
748
+ };
749
+
750
+ svgedit.path.Path.prototype.show = function(y) {
751
+ // Shows this path's segment grips
752
+ this.eachSeg(function() {
753
+ // 'this' is the segment here
754
+ this.show(y);
755
+ });
756
+ if(y) {
757
+ this.selectPt(this.first_seg.index);
758
+ }
759
+ return this;
760
+ };
761
+
762
+ // Move selected points
763
+ svgedit.path.Path.prototype.movePts = function(d_x, d_y) {
764
+ var i = this.selected_pts.length;
765
+ while(i--) {
766
+ var seg = this.segs[this.selected_pts[i]];
767
+ seg.move(d_x, d_y);
768
+ }
769
+ };
770
+
771
+ svgedit.path.Path.prototype.moveCtrl = function(d_x, d_y) {
772
+ var seg = this.segs[this.selected_pts[0]];
773
+ seg.moveCtrl(this.dragctrl, d_x, d_y);
774
+ if(link_control_pts) {
775
+ seg.setLinked(this.dragctrl);
776
+ }
777
+ };
778
+
779
+ svgedit.path.Path.prototype.setSegType = function(new_type) {
780
+ this.storeD();
781
+ var i = this.selected_pts.length;
782
+ var text;
783
+ while(i--) {
784
+ var sel_pt = this.selected_pts[i];
785
+
786
+ // Selected seg
787
+ var cur = this.segs[sel_pt];
788
+ var prev = cur.prev;
789
+ if(!prev) continue;
790
+
791
+ if(!new_type) { // double-click, so just toggle
792
+ text = "Toggle Path Segment Type";
793
+
794
+ // Toggle segment to curve/straight line
795
+ var old_type = cur.type;
796
+
797
+ new_type = (old_type == 6) ? 4 : 6;
798
+ }
799
+
800
+ new_type = new_type-0;
801
+
802
+ var cur_x = cur.item.x;
803
+ var cur_y = cur.item.y;
804
+ var prev_x = prev.item.x;
805
+ var prev_y = prev.item.y;
806
+ var points;
807
+ switch ( new_type ) {
808
+ case 6:
809
+ if(cur.olditem) {
810
+ var old = cur.olditem;
811
+ points = [cur_x,cur_y, old.x1,old.y1, old.x2,old.y2];
812
+ } else {
813
+ var diff_x = cur_x - prev_x;
814
+ var diff_y = cur_y - prev_y;
815
+ // get control points from straight line segment
816
+ /*
817
+ var ct1_x = (prev_x + (diff_y/2));
818
+ var ct1_y = (prev_y - (diff_x/2));
819
+ var ct2_x = (cur_x + (diff_y/2));
820
+ var ct2_y = (cur_y - (diff_x/2));
821
+ */
822
+ //create control points on the line to preserve the shape (WRS)
823
+ var ct1_x = (prev_x + (diff_x/3));
824
+ var ct1_y = (prev_y + (diff_y/3));
825
+ var ct2_x = (cur_x - (diff_x/3));
826
+ var ct2_y = (cur_y - (diff_y/3));
827
+ points = [cur_x,cur_y, ct1_x,ct1_y, ct2_x,ct2_y];
828
+ }
829
+ break;
830
+ case 4:
831
+ points = [cur_x,cur_y];
832
+
833
+ // Store original prevve segment nums
834
+ cur.olditem = cur.item;
835
+ break;
836
+ }
837
+
838
+ cur.setType(new_type, points);
839
+ }
840
+ svgedit.path.path.endChanges(text);
841
+ };
842
+
843
+ svgedit.path.Path.prototype.selectPt = function(pt, ctrl_num) {
844
+ this.clearSelection();
845
+ if(pt == null) {
846
+ this.eachSeg(function(i) {
847
+ // 'this' is the segment here.
848
+ if(this.prev) {
849
+ pt = i;
850
+ }
851
+ });
852
+ }
853
+ this.addPtsToSelection(pt);
854
+ if(ctrl_num) {
855
+ this.dragctrl = ctrl_num;
856
+
857
+ if(link_control_pts) {
858
+ this.segs[pt].setLinked(ctrl_num);
859
+ }
860
+ }
861
+ };
862
+
863
+ // Update position of all points
864
+ svgedit.path.Path.prototype.update = function() {
865
+ var elem = this.elem;
866
+ if(svgedit.utilities.getRotationAngle(elem)) {
867
+ this.matrix = svgedit.math.getMatrix(elem);
868
+ this.imatrix = this.matrix.inverse();
869
+ } else {
870
+ this.matrix = null;
871
+ this.imatrix = null;
872
+ }
873
+
874
+ this.eachSeg(function(i) {
875
+ this.item = elem.pathSegList.getItem(i);
876
+ this.update();
877
+ });
878
+
879
+ return this;
880
+ };
881
+
882
+ svgedit.path.getPath_ = function(elem) {
883
+ var p = pathData[elem.id];
884
+ if(!p) p = pathData[elem.id] = new svgedit.path.Path(elem);
885
+ return p;
886
+ };
887
+
888
+ svgedit.path.removePath_ = function(id) {
889
+ if(id in pathData) delete pathData[id];
890
+ };
891
+
892
+ var getRotVals = function(x, y) {
893
+ dx = x - oldcx;
894
+ dy = y - oldcy;
895
+
896
+ // rotate the point around the old center
897
+ r = Math.sqrt(dx*dx + dy*dy);
898
+ theta = Math.atan2(dy,dx) + angle;
899
+ dx = r * Math.cos(theta) + oldcx;
900
+ dy = r * Math.sin(theta) + oldcy;
901
+
902
+ // dx,dy should now hold the actual coordinates of each
903
+ // point after being rotated
904
+
905
+ // now we want to rotate them around the new center in the reverse direction
906
+ dx -= newcx;
907
+ dy -= newcy;
908
+
909
+ r = Math.sqrt(dx*dx + dy*dy);
910
+ theta = Math.atan2(dy,dx) - angle;
911
+
912
+ return {'x':(r * Math.cos(theta) + newcx)/1,
913
+ 'y':(r * Math.sin(theta) + newcy)/1};
914
+ };
915
+
916
+ // If the path was rotated, we must now pay the piper:
917
+ // Every path point must be rotated into the rotated coordinate system of
918
+ // its old center, then determine the new center, then rotate it back
919
+ // This is because we want the path to remember its rotation
920
+
921
+ // TODO: This is still using ye olde transform methods, can probably
922
+ // be optimized or even taken care of by recalculateDimensions
923
+ svgedit.path.recalcRotatedPath = function() {
924
+ var current_path = svgedit.path.path.elem;
925
+ var angle = svgedit.utilities.getRotationAngle(current_path, true);
926
+ if(!angle) return;
927
+ // selectedBBoxes[0] = svgedit.path.path.oldbbox;
928
+ var box = svgedit.utilities.getBBox(current_path),
929
+ oldbox = svgedit.path.path.oldbbox,//selectedBBoxes[0],
930
+ oldcx = oldbox.x + oldbox.width/2,
931
+ oldcy = oldbox.y + oldbox.height/2,
932
+ newcx = box.x + box.width/2,
933
+ newcy = box.y + box.height/2,
934
+
935
+ // un-rotate the new center to the proper position
936
+ dx = newcx - oldcx,
937
+ dy = newcy - oldcy,
938
+ r = Math.sqrt(dx*dx + dy*dy),
939
+ theta = Math.atan2(dy,dx) + angle;
940
+
941
+ newcx = r * Math.cos(theta) + oldcx;
942
+ newcy = r * Math.sin(theta) + oldcy;
943
+
944
+ var list = current_path.pathSegList,
945
+ i = list.numberOfItems;
946
+ while (i) {
947
+ i -= 1;
948
+ var seg = list.getItem(i),
949
+ type = seg.pathSegType;
950
+ if(type == 1) continue;
951
+
952
+ var rvals = getRotVals(seg.x,seg.y),
953
+ points = [rvals.x, rvals.y];
954
+ if(seg.x1 != null && seg.x2 != null) {
955
+ c_vals1 = getRotVals(seg.x1, seg.y1);
956
+ c_vals2 = getRotVals(seg.x2, seg.y2);
957
+ points.splice(points.length, 0, c_vals1.x , c_vals1.y, c_vals2.x, c_vals2.y);
958
+ }
959
+ svgedit.path.replacePathSeg(type, i, points);
960
+ } // loop for each point
961
+
962
+ box = svgedit.utilities.getBBox(current_path);
963
+ // selectedBBoxes[0].x = box.x; selectedBBoxes[0].y = box.y;
964
+ // selectedBBoxes[0].width = box.width; selectedBBoxes[0].height = box.height;
965
+
966
+ // now we must set the new transform to be rotated around the new center
967
+ var R_nc = svgroot.createSVGTransform(),
968
+ tlist = svgedit.transformlist.getTransformList(current_path);
969
+ R_nc.setRotate((angle * 180.0 / Math.PI), newcx, newcy);
970
+ tlist.replaceItem(R_nc,0);
971
+ };
972
+
973
+ // ====================================
974
+ // Public API starts here
975
+
976
+ svgedit.path.clearData = function() {
977
+ pathData = {};
978
+ };
979
+
980
+ })();