From e44a7e37b6c7b5961adaffc62b9042b8d442938e Mon Sep 17 00:00:00 2001 From: mensonge Date: Thu, 13 Nov 2008 09:49:11 +0000 Subject: New feature: basic Ajax suggestion for tags and implementation of Dojo toolkit git-svn-id: https://semanticscuttle.svn.sourceforge.net/svnroot/semanticscuttle/trunk@151 b3834d28-1941-0410-a4f8-b48e95affb8f --- includes/js/dojox/gfx/Moveable.js | 101 ++ includes/js/dojox/gfx/Mover.js | 62 + includes/js/dojox/gfx/README | 102 ++ includes/js/dojox/gfx/_base.js | 288 ++++ includes/js/dojox/gfx/arc.js | 122 ++ includes/js/dojox/gfx/attach.js | 7 + includes/js/dojox/gfx/canvas.js | 687 ++++++++ includes/js/dojox/gfx/canvas_attach.js | 8 + includes/js/dojox/gfx/decompose.js | 139 ++ includes/js/dojox/gfx/demos/beautify.html | 48 + includes/js/dojox/gfx/demos/butterfly.html | 88 + includes/js/dojox/gfx/demos/career_test.html | 467 +++++ includes/js/dojox/gfx/demos/circles.html | 90 + includes/js/dojox/gfx/demos/clock.html | 253 +++ includes/js/dojox/gfx/demos/clockWidget.html | 332 ++++ includes/js/dojox/gfx/demos/clock_black.html | 253 +++ includes/js/dojox/gfx/demos/creator.html | 123 ++ includes/js/dojox/gfx/demos/data/Lars.json | 1823 ++++++++++++++++++++ includes/js/dojox/gfx/demos/data/Lars.svg | 531 ++++++ includes/js/dojox/gfx/demos/data/LarsDreaming.json | 1823 ++++++++++++++++++++ includes/js/dojox/gfx/demos/data/LarsDreaming.svg | 536 ++++++ includes/js/dojox/gfx/demos/data/Nils.json | 717 ++++++++ includes/js/dojox/gfx/demos/data/Nils.svg | 188 ++ includes/js/dojox/gfx/demos/data/buratino-bg.png | Bin 0 -> 27507 bytes includes/js/dojox/gfx/demos/data/buratino-head.png | Bin 0 -> 30696 bytes .../js/dojox/gfx/demos/data/buratino-left-arm.png | Bin 0 -> 9631 bytes .../js/dojox/gfx/demos/data/buratino-left-leg.png | Bin 0 -> 21682 bytes .../js/dojox/gfx/demos/data/buratino-lollipop.png | Bin 0 -> 21976 bytes .../dojox/gfx/demos/data/buratino-nose-large.png | Bin 0 -> 4182 bytes .../dojox/gfx/demos/data/buratino-nose-medium.png | Bin 0 -> 2587 bytes .../js/dojox/gfx/demos/data/buratino-right-arm.png | Bin 0 -> 13033 bytes .../js/dojox/gfx/demos/data/buratino-right-leg.png | Bin 0 -> 23025 bytes .../js/dojox/gfx/demos/data/buratino-torso.png | Bin 0 -> 23405 bytes includes/js/dojox/gfx/demos/data/buratino.jpg | Bin 0 -> 33344 bytes includes/js/dojox/gfx/demos/data/buratino.json | 12 + includes/js/dojox/gfx/demos/data/svg2gfx.xsl | 72 + includes/js/dojox/gfx/demos/data/transform.json | 1567 +++++++++++++++++ includes/js/dojox/gfx/demos/images/clock_face.jpg | Bin 0 -> 31088 bytes .../js/dojox/gfx/demos/images/clock_face_black.jpg | Bin 0 -> 17347 bytes includes/js/dojox/gfx/demos/inspector.html | 165 ++ includes/js/dojox/gfx/demos/lion.html | 235 +++ includes/js/dojox/gfx/demos/roundedPane.html | 191 ++ includes/js/dojox/gfx/demos/tiger.html | 566 ++++++ includes/js/dojox/gfx/demos/tooltip.html | 238 +++ includes/js/dojox/gfx/fx.js | 281 +++ includes/js/dojox/gfx/matrix.js | 444 +++++ includes/js/dojox/gfx/move.js | 8 + includes/js/dojox/gfx/path.js | 361 ++++ includes/js/dojox/gfx/shape.js | 691 ++++++++ includes/js/dojox/gfx/silverlight.js | 693 ++++++++ includes/js/dojox/gfx/silverlight_attach.js | 87 + includes/js/dojox/gfx/svg.js | 638 +++++++ includes/js/dojox/gfx/svg_attach.js | 224 +++ includes/js/dojox/gfx/tests/decompose.js | 114 ++ includes/js/dojox/gfx/tests/matrix.js | 228 +++ includes/js/dojox/gfx/tests/module.js | 13 + includes/js/dojox/gfx/tests/runTests.html | 9 + includes/js/dojox/gfx/tests/test_arc.html | 71 + includes/js/dojox/gfx/tests/test_bezier.html | 85 + includes/js/dojox/gfx/tests/test_decompose.html | 54 + includes/js/dojox/gfx/tests/test_fill.html | 47 + includes/js/dojox/gfx/tests/test_fx.html | 113 ++ includes/js/dojox/gfx/tests/test_gfx.html | 489 ++++++ includes/js/dojox/gfx/tests/test_gradient.html | 70 + includes/js/dojox/gfx/tests/test_group.html | 73 + includes/js/dojox/gfx/tests/test_image1.html | 74 + includes/js/dojox/gfx/tests/test_image2.html | 50 + .../js/dojox/gfx/tests/test_linearGradient.html | 80 + includes/js/dojox/gfx/tests/test_linestyle.html | 45 + includes/js/dojox/gfx/tests/test_pattern.html | 44 + includes/js/dojox/gfx/tests/test_poly.html | 53 + includes/js/dojox/gfx/tests/test_resize.html | 61 + includes/js/dojox/gfx/tests/test_setPath.html | 76 + includes/js/dojox/gfx/tests/test_tbbox.html | 117 ++ includes/js/dojox/gfx/tests/test_text.html | 88 + includes/js/dojox/gfx/tests/test_textpath.html | 76 + includes/js/dojox/gfx/tests/test_transform.html | 98 ++ includes/js/dojox/gfx/utils.js | 87 + includes/js/dojox/gfx/vml.js | 1165 +++++++++++++ includes/js/dojox/gfx/vml_attach.js | 362 ++++ 80 files changed, 19103 insertions(+) create mode 100644 includes/js/dojox/gfx/Moveable.js create mode 100644 includes/js/dojox/gfx/Mover.js create mode 100644 includes/js/dojox/gfx/README create mode 100644 includes/js/dojox/gfx/_base.js create mode 100644 includes/js/dojox/gfx/arc.js create mode 100644 includes/js/dojox/gfx/attach.js create mode 100644 includes/js/dojox/gfx/canvas.js create mode 100644 includes/js/dojox/gfx/canvas_attach.js create mode 100644 includes/js/dojox/gfx/decompose.js create mode 100644 includes/js/dojox/gfx/demos/beautify.html create mode 100644 includes/js/dojox/gfx/demos/butterfly.html create mode 100644 includes/js/dojox/gfx/demos/career_test.html create mode 100644 includes/js/dojox/gfx/demos/circles.html create mode 100644 includes/js/dojox/gfx/demos/clock.html create mode 100644 includes/js/dojox/gfx/demos/clockWidget.html create mode 100644 includes/js/dojox/gfx/demos/clock_black.html create mode 100644 includes/js/dojox/gfx/demos/creator.html create mode 100644 includes/js/dojox/gfx/demos/data/Lars.json create mode 100644 includes/js/dojox/gfx/demos/data/Lars.svg create mode 100644 includes/js/dojox/gfx/demos/data/LarsDreaming.json create mode 100644 includes/js/dojox/gfx/demos/data/LarsDreaming.svg create mode 100644 includes/js/dojox/gfx/demos/data/Nils.json create mode 100644 includes/js/dojox/gfx/demos/data/Nils.svg create mode 100644 includes/js/dojox/gfx/demos/data/buratino-bg.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-head.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-left-arm.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-left-leg.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-lollipop.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-nose-large.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-nose-medium.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-right-arm.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-right-leg.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino-torso.png create mode 100644 includes/js/dojox/gfx/demos/data/buratino.jpg create mode 100644 includes/js/dojox/gfx/demos/data/buratino.json create mode 100644 includes/js/dojox/gfx/demos/data/svg2gfx.xsl create mode 100644 includes/js/dojox/gfx/demos/data/transform.json create mode 100644 includes/js/dojox/gfx/demos/images/clock_face.jpg create mode 100644 includes/js/dojox/gfx/demos/images/clock_face_black.jpg create mode 100644 includes/js/dojox/gfx/demos/inspector.html create mode 100644 includes/js/dojox/gfx/demos/lion.html create mode 100644 includes/js/dojox/gfx/demos/roundedPane.html create mode 100644 includes/js/dojox/gfx/demos/tiger.html create mode 100644 includes/js/dojox/gfx/demos/tooltip.html create mode 100644 includes/js/dojox/gfx/fx.js create mode 100644 includes/js/dojox/gfx/matrix.js create mode 100644 includes/js/dojox/gfx/move.js create mode 100644 includes/js/dojox/gfx/path.js create mode 100644 includes/js/dojox/gfx/shape.js create mode 100644 includes/js/dojox/gfx/silverlight.js create mode 100644 includes/js/dojox/gfx/silverlight_attach.js create mode 100644 includes/js/dojox/gfx/svg.js create mode 100644 includes/js/dojox/gfx/svg_attach.js create mode 100644 includes/js/dojox/gfx/tests/decompose.js create mode 100644 includes/js/dojox/gfx/tests/matrix.js create mode 100644 includes/js/dojox/gfx/tests/module.js create mode 100644 includes/js/dojox/gfx/tests/runTests.html create mode 100644 includes/js/dojox/gfx/tests/test_arc.html create mode 100644 includes/js/dojox/gfx/tests/test_bezier.html create mode 100644 includes/js/dojox/gfx/tests/test_decompose.html create mode 100644 includes/js/dojox/gfx/tests/test_fill.html create mode 100644 includes/js/dojox/gfx/tests/test_fx.html create mode 100644 includes/js/dojox/gfx/tests/test_gfx.html create mode 100644 includes/js/dojox/gfx/tests/test_gradient.html create mode 100644 includes/js/dojox/gfx/tests/test_group.html create mode 100644 includes/js/dojox/gfx/tests/test_image1.html create mode 100644 includes/js/dojox/gfx/tests/test_image2.html create mode 100644 includes/js/dojox/gfx/tests/test_linearGradient.html create mode 100644 includes/js/dojox/gfx/tests/test_linestyle.html create mode 100644 includes/js/dojox/gfx/tests/test_pattern.html create mode 100644 includes/js/dojox/gfx/tests/test_poly.html create mode 100644 includes/js/dojox/gfx/tests/test_resize.html create mode 100644 includes/js/dojox/gfx/tests/test_setPath.html create mode 100644 includes/js/dojox/gfx/tests/test_tbbox.html create mode 100644 includes/js/dojox/gfx/tests/test_text.html create mode 100644 includes/js/dojox/gfx/tests/test_textpath.html create mode 100644 includes/js/dojox/gfx/tests/test_transform.html create mode 100644 includes/js/dojox/gfx/utils.js create mode 100644 includes/js/dojox/gfx/vml.js create mode 100644 includes/js/dojox/gfx/vml_attach.js (limited to 'includes/js/dojox/gfx') diff --git a/includes/js/dojox/gfx/Moveable.js b/includes/js/dojox/gfx/Moveable.js new file mode 100644 index 0000000..2717043 --- /dev/null +++ b/includes/js/dojox/gfx/Moveable.js @@ -0,0 +1,101 @@ +if(!dojo._hasResource["dojox.gfx.Moveable"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.Moveable"] = true; +dojo.provide("dojox.gfx.Moveable"); + +dojo.require("dojox.gfx.Mover"); + +dojo.declare("dojox.gfx.Moveable", null, { + constructor: function(shape, params){ + // summary: an object, which makes a shape moveable + // shape: dojox.gfx.Shape: a shape object to be moved + // params: Object: an optional object with additional parameters; + // following parameters are recognized: + // delay: Number: delay move by this number of pixels + // mover: Object: a constructor of custom Mover + this.shape = shape; + this.delay = (params && params.delay > 0) ? params.delay : 0; + this.mover = (params && params.mover) ? params.mover : dojox.gfx.Mover; + this.events = [ + this.shape.connect("onmousedown", this, "onMouseDown"), + // cancel text selection and text dragging + //dojo.connect(this.handle, "ondragstart", dojo, "stopEvent"), + //dojo.connect(this.handle, "onselectstart", dojo, "stopEvent") + ]; + }, + + // methods + destroy: function(){ + // summary: stops watching for possible move, deletes all references, so the object can be garbage-collected + dojo.forEach(this.events, this.shape.disconnect, this.shape); + this.events = this.shape = null; + }, + + // mouse event processors + onMouseDown: function(e){ + // summary: event processor for onmousedown, creates a Mover for the shape + // e: Event: mouse event + if(this.delay){ + this.events.push(this.shape.connect("onmousemove", this, "onMouseMove")); + this.events.push(this.shape.connect("onmouseup", this, "onMouseUp")); + this._lastX = e.clientX; + this._lastY = e.clientY; + }else{ + new this.mover(this.shape, e, this); + } + dojo.stopEvent(e); + }, + onMouseMove: function(e){ + // summary: event processor for onmousemove, used only for delayed drags + // e: Event: mouse event + if(Math.abs(e.clientX - this._lastX) > this.delay || Math.abs(e.clientY - this._lastY) > this.delay){ + this.onMouseUp(e); + new this.mover(this.shape, e, this); + } + dojo.stopEvent(e); + }, + onMouseUp: function(e){ + // summary: event processor for onmouseup, used only for delayed delayed drags + // e: Event: mouse event + this.shape.disconnect(this.events.pop()); + this.shape.disconnect(this.events.pop()); + }, + + // local events + onMoveStart: function(/* dojox.gfx.Mover */ mover){ + // summary: called before every move operation + dojo.publish("/gfx/move/start", [mover]); + dojo.addClass(dojo.body(), "dojoMove"); + }, + onMoveStop: function(/* dojox.gfx.Mover */ mover){ + // summary: called after every move operation + dojo.publish("/gfx/move/stop", [mover]); + dojo.removeClass(dojo.body(), "dojoMove"); + }, + onFirstMove: function(/* dojox.gfx.Mover */ mover){ + // summary: called during the very first move notification, + // can be used to initialize coordinates, can be overwritten. + + // default implementation does nothing + }, + onMove: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){ + // summary: called during every move notification, + // should actually move the node, can be overwritten. + this.onMoving(mover, shift); + this.shape.applyLeftTransform(shift); + this.onMoved(mover, shift); + }, + onMoving: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){ + // summary: called before every incremental move, + // can be overwritten. + + // default implementation does nothing + }, + onMoved: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){ + // summary: called after every incremental move, + // can be overwritten. + + // default implementation does nothing + } +}); + +} diff --git a/includes/js/dojox/gfx/Mover.js b/includes/js/dojox/gfx/Mover.js new file mode 100644 index 0000000..6a5d456 --- /dev/null +++ b/includes/js/dojox/gfx/Mover.js @@ -0,0 +1,62 @@ +if(!dojo._hasResource["dojox.gfx.Mover"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.Mover"] = true; +dojo.provide("dojox.gfx.Mover"); + +dojo.declare("dojox.gfx.Mover", null, { + constructor: function(shape, e, host){ + // summary: an object, which makes a shape follow the mouse, + // used as a default mover, and as a base class for custom movers + // shape: dojox.gfx.Shape: a shape object to be moved + // e: Event: a mouse event, which started the move; + // only clientX and clientY properties are used + // host: Object?: object which implements the functionality of the move, + // and defines proper events (onMoveStart and onMoveStop) + this.shape = shape; + this.lastX = e.clientX + this.lastY = e.clientY; + var h = this.host = host, d = document, + firstEvent = dojo.connect(d, "onmousemove", this, "onFirstMove"); + this.events = [ + dojo.connect(d, "onmousemove", this, "onMouseMove"), + dojo.connect(d, "onmouseup", this, "destroy"), + // cancel text selection and text dragging + dojo.connect(d, "ondragstart", dojo, "stopEvent"), + dojo.connect(d, "onselectstart", dojo, "stopEvent"), + firstEvent + ]; + // notify that the move has started + if(h && h.onMoveStart){ + h.onMoveStart(this); + } + }, + // mouse event processors + onMouseMove: function(e){ + // summary: event processor for onmousemove + // e: Event: mouse event + var x = e.clientX; + var y = e.clientY; + this.host.onMove(this, {dx: x - this.lastX, dy: y - this.lastY}); + this.lastX = x; + this.lastY = y; + dojo.stopEvent(e); + }, + // utilities + onFirstMove: function(){ + // summary: it is meant to be called only once + this.host.onFirstMove(this); + dojo.disconnect(this.events.pop()); + }, + destroy: function(){ + // summary: stops the move, deletes all references, so the object can be garbage-collected + dojo.forEach(this.events, dojo.disconnect); + // undo global settings + var h = this.host; + if(h && h.onMoveStop){ + h.onMoveStop(this); + } + // destroy objects + this.events = this.shape = null; + } +}); + +} diff --git a/includes/js/dojox/gfx/README b/includes/js/dojox/gfx/README new file mode 100644 index 0000000..c318ddb --- /dev/null +++ b/includes/js/dojox/gfx/README @@ -0,0 +1,102 @@ +------------------------------------------------------------------------------- +dojox.gfx +------------------------------------------------------------------------------- +Version 1.100 +Release date: 08/01/2006 +------------------------------------------------------------------------------- +Project state: +beta +HTMLCanvas renderer: experimental +------------------------------------------------------------------------------- +Credits + Eugene Lazutkin (eugene.lazutkin@gmail.com) + Kun Xi (bookstack@gmail.com) + Chris Mitchell (ccmitchellusa@gmail.com) HTML Canvas +------------------------------------------------------------------------------- +Project description + +Implementation of simple portable 2D graphics library. +------------------------------------------------------------------------------- +Dependencies: + +Dojo Core +------------------------------------------------------------------------------- +Documentation + +Currently it can be found here: http://docs.google.com/Doc?id=d764479_1hnb2tn + +HTMLCanvas Renderer Status + +To use canvas rendering, insert 'canvas' at the beginning of the gfxRenderers list in your +djConfig, for example: + +canvas currently will only render on non-IE browsers (see dojox/gfx.js for where the renderer is loaded); +although it should be possible to use an IE canvas implementation (like Google's); however, it will be very slow. + +The following tests can be made to work with HTML Canvas with minor testcase modification: +dojox/gfx/tests + test_gfx.html-Bugs #1 + test_arc.html + test_bezier.html + test_pattern.html + test_gradient.html + test_linearGradient.html + test_image1.html - Limitation #3 + test_transform.html - Bug #1 + test_poly.html - Bug #1 +dojox/gfx/demos + butterfly.html - Bug #1 + lion.html - Bug #1 + tiger.html - Bug #1 + circles.html - No event processing yet :( + creator.html +dojox/chart + test_pie2d.html - Dojo Charts on iPhone anyone? :) + test_chart2d.html - + + // To make charts work, the following line needs to be added to the end of the + // Chart2D.js render() method (prior to return) + if(this.surface.render){this.surface.render()}; + +Known Limitations: +1) event handling- plan is to capture all events at canvas, perform intersect/hit + tests (not implemented) against scene graph, then propogate event to top-most + intersected shape. HtmlCanvas shape need intersectsStroke and intersectsBounds, + and intersects (region). +2) SVG and VML are "live" scene graphs; eg. any state change to objects in the + scene automatically get rendered in next engine render pass. For canvas, it's + procedural, and current implementation requires application to call surface.render() + whenever scene needs to be updated. Plan is to do dirty region checking based + on bounding boxes (currently not properly computed), and track dirty areas anytime + state changes (invalidate) separate from render phase. + Add the following call where changes to the scene graph are complete and you want to + render: + + if (surface.render){surface.render();} + +4) Text/Text Paths - Text shape is implemented using DIV overlays. Many text styles are not + applied, and outline/fills are not possible. This is due to limitations in Canvas spec. + Firefox 3.0 has proprietary text functions that we could test for and use once FF3 is out. + No luck on Safari. +3) No Image skewing - Limitation of Canvas + +Known Bugs: +1) Matrix xformations (applied from root to shape leaf nodes) not quite right--but very close. + Canvas does not have a built in transformation function that allows skewing. Need to + track skew matrix with Shape, and perform other trans/rot/scale transformations without + using canvas transform functions. + + +------------------------------------------------------------------------------- +Installation instructions + +Grab the following from the Dojo SVN Repository: +http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gfx.js +http://svn.dojotoolkit.org/var/src/dojo/dojox/trunk/gfx/* + +Install into the following directory structure: +/dojox/gfx/ + +...which should be at the same level as your Dojo checkout. +------------------------------------------------------------------------------- diff --git a/includes/js/dojox/gfx/_base.js b/includes/js/dojox/gfx/_base.js new file mode 100644 index 0000000..3b118c2 --- /dev/null +++ b/includes/js/dojox/gfx/_base.js @@ -0,0 +1,288 @@ +if(!dojo._hasResource["dojox.gfx._base"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx._base"] = true; +dojo.provide("dojox.gfx._base"); + +(function(){ + var g = dojox.gfx, b = g._base; + + // candidates for dojox.style (work on VML and SVG nodes) + g._hasClass = function(/*DomNode*/node, /*String*/classStr){ + // summary: + // Returns whether or not the specified classes are a portion of the + // class list currently applied to the node. + // return (new RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className) // Boolean + return ((" "+node.getAttribute("className")+" ").indexOf(" "+classStr+" ") >= 0); // Boolean + } + g._addClass = function(/*DomNode*/node, /*String*/classStr){ + // summary: + // Adds the specified classes to the end of the class list on the + // passed node. + var cls = node.getAttribute("className"); + if((" "+cls+" ").indexOf(" "+classStr+" ") < 0){ + node.setAttribute("className", cls + (cls ? ' ' : '') + classStr); + } + } + g._removeClass = function(/*DomNode*/node, /*String*/classStr){ + // summary: Removes classes from node. + node.setAttribute("className", node.getAttribute("className").replace(new RegExp('(^|\\s+)'+classStr+'(\\s+|$)'), "$1$2")); + } + + + // candidate for dojox.html.metrics (dynamic font resize handler is not implemented here) + + // derived from Morris John's emResized measurer + b._getFontMeasurements = function(){ + // summary + // Returns an object that has pixel equivilents of standard font size values. + var heights = { + '1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0, + 'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0 + }; + + if(dojo.isIE){ + // we do a font-size fix if and only if one isn't applied already. + // NOTE: If someone set the fontSize on the HTML Element, this will kill it. + dojo.doc.documentElement.style.fontSize="100%"; + } + + // set up the measuring node. + var div=dojo.doc.createElement("div"); + div.style.position="absolute"; + div.style.left="-100px"; + div.style.top="0"; + div.style.width="30px"; + div.style.height="1000em"; + div.style.border="0"; + div.style.margin="0"; + div.style.padding="0"; + div.style.outline="0"; + div.style.lineHeight="1"; + div.style.overflow="hidden"; + dojo.body().appendChild(div); + + // do the measurements. + for(var p in heights){ + div.style.fontSize = p; + heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000; + } + + dojo.body().removeChild(div); + div = null; + return heights; // object + }; + + var fontMeasurements = null; + + b._getCachedFontMeasurements = function(recalculate){ + if(recalculate || !fontMeasurements){ + fontMeasurements = b._getFontMeasurements(); + } + return fontMeasurements; + }; + + // candidate for dojox.html.metrics + + var measuringNode = null, empty = {}; + b._getTextBox = function(/* String */ text, /* Object */ style, /* String? */ className){ + var m; + if(!measuringNode){ + m = measuringNode = dojo.doc.createElement("div"); + m.style.position = "absolute"; + m.style.left = "-10000px"; + m.style.top = "0"; + dojo.body().appendChild(m); + }else{ + m = measuringNode; + } + // reset styles + m.className = ""; + m.style.border = "0"; + m.style.margin = "0"; + m.style.padding = "0"; + m.style.outline = "0"; + // set new style + if(arguments.length > 1 && style){ + for(var i in style){ + if(i in empty){ continue; } + m.style[i] = style[i]; + } + } + // set classes + if(arguments.length > 2 && className){ + m.className = className; + } + // take a measure + m.innerHTML = text; + return dojo.marginBox(m); + }; + + // candidate for dojo.dom + + var uniqueId = 0; + b._getUniqueId = function(){ + // summary: returns a unique string for use with any DOM element + var id; + do{ + id = dojo._scopeName + "Unique" + (++uniqueId); + }while(dojo.byId(id)); + return id; + }; +})(); + +dojo.mixin(dojox.gfx, { + // summary: defines constants, prototypes, and utility functions + + // default shapes, which are used to fill in missing parameters + defaultPath: {type: "path", path: ""}, + defaultPolyline: {type: "polyline", points: []}, + defaultRect: {type: "rect", x: 0, y: 0, width: 100, height: 100, r: 0}, + defaultEllipse: {type: "ellipse", cx: 0, cy: 0, rx: 200, ry: 100}, + defaultCircle: {type: "circle", cx: 0, cy: 0, r: 100}, + defaultLine: {type: "line", x1: 0, y1: 0, x2: 100, y2: 100}, + defaultImage: {type: "image", x: 0, y: 0, width: 0, height: 0, src: ""}, + defaultText: {type: "text", x: 0, y: 0, text: "", + align: "start", decoration: "none", rotated: false, kerning: true }, + defaultTextPath: {type: "textpath", text: "", + align: "start", decoration: "none", rotated: false, kerning: true }, + + // default geometric attributes + defaultStroke: {type: "stroke", color: "black", style: "solid", width: 1, cap: "butt", join: 4}, + defaultLinearGradient: {type: "linear", x1: 0, y1: 0, x2: 100, y2: 100, + colors: [{offset: 0, color: "black"}, {offset: 1, color: "white"}]}, + defaultRadialGradient: {type: "radial", cx: 0, cy: 0, r: 100, + colors: [{offset: 0, color: "black"}, {offset: 1, color: "white"}]}, + defaultPattern: {type: "pattern", x: 0, y: 0, width: 0, height: 0, src: ""}, + defaultFont: {type: "font", style: "normal", variant: "normal", weight: "normal", + size: "10pt", family: "serif"}, + + normalizeColor: function(/*Color*/ color){ + // summary: converts any legal color representation to normalized dojo.Color object + return (color instanceof dojo.Color) ? color : new dojo.Color(color); // dojo.Color + }, + normalizeParameters: function(existed, update){ + // summary: updates an existing object with properties from an "update" object + // existed: Object: the "target" object to be updated + // update: Object: the "update" object, whose properties will be used to update the existed object + if(update){ + var empty = {}; + for(var x in existed){ + if(x in update && !(x in empty)){ + existed[x] = update[x]; + } + } + } + return existed; // Object + }, + makeParameters: function(defaults, update){ + // summary: copies the original object, and all copied properties from the "update" object + // defaults: Object: the object to be cloned before updating + // update: Object: the object, which properties are to be cloned during updating + if(!update) return dojo.clone(defaults); + var result = {}; + for(var i in defaults){ + if(!(i in result)){ + result[i] = dojo.clone((i in update) ? update[i] : defaults[i]); + } + } + return result; // Object + }, + formatNumber: function(x, addSpace){ + // summary: converts a number to a string using a fixed notation + // x: Number: number to be converted + // addSpace: Boolean?: if it is true, add a space before a positive number + var val = x.toString(); + if(val.indexOf("e") >= 0){ + val = x.toFixed(4); + }else{ + var point = val.indexOf("."); + if(point >= 0 && val.length - point > 5){ + val = x.toFixed(4); + } + } + if(x < 0){ + return val; // String + } + return addSpace ? " " + val : val; // String + }, + // font operations + makeFontString: function(font){ + // summary: converts a font object to a CSS font string + // font: Object: font object (see dojox.gfx.defaultFont) + return font.style + " " + font.variant + " " + font.weight + " " + font.size + " " + font.family; // Object + }, + splitFontString: function(str){ + // summary: converts a CSS font string to a font object + // str: String: a CSS font string + var font = dojo.clone(dojox.gfx.defaultFont); + var t = str.split(/\s+/); + do{ + if(t.length < 5){ break; } + font.style = t[0]; + font.varian = t[1]; + font.weight = t[2]; + var i = t[3].indexOf("/"); + font.size = i < 0 ? t[3] : t[3].substring(0, i); + var j = 4; + if(i < 0){ + if(t[4] == "/"){ + j = 6; + break; + } + if(t[4].substr(0, 1) == "/"){ + j = 5; + break; + } + } + if(j + 3 > t.length){ break; } + font.size = t[j]; + font.family = t[j + 1]; + }while(false); + return font; // Object + }, + // length operations + cm_in_pt: 72 / 2.54, // Number: centimeters per inch + mm_in_pt: 7.2 / 2.54, // Number: millimeters per inch + px_in_pt: function(){ + // summary: returns a number of pixels per point + return dojox.gfx._base._getCachedFontMeasurements()["12pt"] / 12; // Number + }, + pt2px: function(len){ + // summary: converts points to pixels + // len: Number: a value in points + return len * dojox.gfx.px_in_pt(); // Number + }, + px2pt: function(len){ + // summary: converts pixels to points + // len: Number: a value in pixels + return len / dojox.gfx.px_in_pt(); // Number + }, + normalizedLength: function(len) { + // summary: converts any length value to pixels + // len: String: a length, e.g., "12pc" + if(len.length == 0) return 0; + if(len.length > 2){ + var px_in_pt = dojox.gfx.px_in_pt(); + var val = parseFloat(len); + switch(len.slice(-2)){ + case "px": return val; + case "pt": return val * px_in_pt; + case "in": return val * 72 * px_in_pt; + case "pc": return val * 12 * px_in_pt; + case "mm": return val / dojox.gfx.mm_in_pt * px_in_pt; + case "cm": return val / dojox.gfx.cm_in_pt * px_in_pt; + } + } + return parseFloat(len); // Number + }, + + // a constant used to split a SVG/VML path into primitive components + pathVmlRegExp: /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g, + pathSvgRegExp: /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g, + + equalSources: function(a, b){ + // summary: compares event sources, returns true if they are equal + return a && b && a == b; + } +}); + +} diff --git a/includes/js/dojox/gfx/arc.js b/includes/js/dojox/gfx/arc.js new file mode 100644 index 0000000..4a0eade --- /dev/null +++ b/includes/js/dojox/gfx/arc.js @@ -0,0 +1,122 @@ +if(!dojo._hasResource["dojox.gfx.arc"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.arc"] = true; +dojo.provide("dojox.gfx.arc"); + +dojo.require("dojox.gfx.matrix"); + +(function(){ + var m = dojox.gfx.matrix, + unitArcAsBezier = function(alpha){ + // summary: return a start point, 1st and 2nd control points, and an end point of + // a an arc, which is reflected on the x axis + // alpha: Number: angle in radians, the arc will be 2 * angle size + var cosa = Math.cos(alpha), sina = Math.sin(alpha), + p2 = {x: cosa + (4 / 3) * (1 - cosa), y: sina - (4 / 3) * cosa * (1 - cosa) / sina}; + return { // Object + s: {x: cosa, y: -sina}, + c1: {x: p2.x, y: -p2.y}, + c2: p2, + e: {x: cosa, y: sina} + }; + }, + twoPI = 2 * Math.PI, pi4 = Math.PI / 4, pi8 = Math.PI / 8, + pi48 = pi4 + pi8, curvePI4 = unitArcAsBezier(pi8); + + dojo.mixin(dojox.gfx.arc, { + unitArcAsBezier: unitArcAsBezier, + curvePI4: curvePI4, + arcAsBezier: function(last, rx, ry, xRotg, large, sweep, x, y){ + // summary: calculates an arc as a series of Bezier curves + // given the last point and a standard set of SVG arc parameters, + // it returns an array of arrays of parameters to form a series of + // absolute Bezier curves. + // last: Object: a point-like object as a start of the arc + // rx: Number: a horizontal radius for the virtual ellipse + // ry: Number: a vertical radius for the virtual ellipse + // xRotg: Number: a rotation of an x axis of the virtual ellipse in degrees + // large: Boolean: which part of the ellipse will be used (the larger arc if true) + // sweep: Boolean: direction of the arc (CW if true) + // x: Number: the x coordinate of the end point of the arc + // y: Number: the y coordinate of the end point of the arc + + // calculate parameters + large = Boolean(large); + sweep = Boolean(sweep); + var xRot = m._degToRad(xRotg), + rx2 = rx * rx, ry2 = ry * ry, + pa = m.multiplyPoint( + m.rotate(-xRot), + {x: (last.x - x) / 2, y: (last.y - y) / 2} + ), + pax2 = pa.x * pa.x, pay2 = pa.y * pa.y, + c1 = Math.sqrt((rx2 * ry2 - rx2 * pay2 - ry2 * pax2) / (rx2 * pay2 + ry2 * pax2)); + if(isNaN(c1)){ c1 = 0; } + var ca = { + x: c1 * rx * pa.y / ry, + y: -c1 * ry * pa.x / rx + }; + if(large == sweep){ + ca = {x: -ca.x, y: -ca.y}; + } + // the center + var c = m.multiplyPoint( + [ + m.translate( + (last.x + x) / 2, + (last.y + y) / 2 + ), + m.rotate(xRot) + ], + ca + ); + // calculate the elliptic transformation + var elliptic_transform = m.normalize([ + m.translate(c.x, c.y), + m.rotate(xRot), + m.scale(rx, ry) + ]); + // start, end, and size of our arc + var inversed = m.invert(elliptic_transform), + sp = m.multiplyPoint(inversed, last), + ep = m.multiplyPoint(inversed, x, y), + startAngle = Math.atan2(sp.y, sp.x), + endAngle = Math.atan2(ep.y, ep.x), + theta = startAngle - endAngle; // size of our arc in radians + if(sweep){ theta = -theta; } + if(theta < 0){ + theta += twoPI; + }else if(theta > twoPI){ + theta -= twoPI; + } + + // draw curve chunks + var alpha = pi8, curve = curvePI4, step = sweep ? alpha : -alpha, + result = []; + for(var angle = theta; angle > 0; angle -= pi4){ + if(angle < pi48){ + alpha = angle / 2; + curve = unitArcAsBezier(alpha); + step = sweep ? alpha : -alpha; + angle = 0; // stop the loop + } + var c1, c2, e, + M = m.normalize([elliptic_transform, m.rotate(startAngle + step)]); + if(sweep){ + c1 = m.multiplyPoint(M, curve.c1); + c2 = m.multiplyPoint(M, curve.c2); + e = m.multiplyPoint(M, curve.e ); + }else{ + c1 = m.multiplyPoint(M, curve.c2); + c2 = m.multiplyPoint(M, curve.c1); + e = m.multiplyPoint(M, curve.s ); + } + // draw the curve + result.push([c1.x, c1.y, c2.x, c2.y, e.x, e.y]); + startAngle += 2 * step; + } + return result; // Object + } + }); +})(); + +} diff --git a/includes/js/dojox/gfx/attach.js b/includes/js/dojox/gfx/attach.js new file mode 100644 index 0000000..901f66f --- /dev/null +++ b/includes/js/dojox/gfx/attach.js @@ -0,0 +1,7 @@ +dojo.require("dojox.gfx"); + +// include an attacher conditionally +dojo.requireIf(dojox.gfx.renderer == "svg", "dojox.gfx.svg_attach"); +dojo.requireIf(dojox.gfx.renderer == "vml", "dojox.gfx.vml_attach"); +dojo.requireIf(dojox.gfx.renderer == "silverlight", "dojox.gfx.silverlight_attach"); +dojo.requireIf(dojox.gfx.renderer == "canvas", "dojox.gfx.canvas_attach"); diff --git a/includes/js/dojox/gfx/canvas.js b/includes/js/dojox/gfx/canvas.js new file mode 100644 index 0000000..6872b2f --- /dev/null +++ b/includes/js/dojox/gfx/canvas.js @@ -0,0 +1,687 @@ +if(!dojo._hasResource["dojox.gfx.canvas"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.canvas"] = true; +dojo.provide("dojox.gfx.canvas"); + +dojo.require("dojox.gfx._base"); +dojo.require("dojox.gfx.shape"); +dojo.require("dojox.gfx.path"); +dojo.require("dojox.gfx.arc"); +dojo.require("dojox.gfx.decompose"); + +dojo.experimental("dojox.gfx.canvas"); + +(function(){ + var g = dojox.gfx, gs = g.shape, ga = g.arc, + m = g.matrix, mp = m.multiplyPoint, pi = Math.PI, twoPI = 2 * pi, halfPI = pi /2; + + dojo.extend(g.Shape, { + _render: function(/* Object */ ctx){ + // summary: render the shape + ctx.save(); + this._renderTransform(ctx); + this._renderShape(ctx); + this._renderFill(ctx, true); + this._renderStroke(ctx, true); + ctx.restore(); + }, + _renderTransform: function(/* Object */ ctx){ + if("canvasTransform" in this){ + var t = this.canvasTransform; + ctx.translate(t.dx, t.dy); + ctx.rotate(t.angle2); + ctx.scale(t.sx, t.sy); + ctx.rotate(t.angle1); + // The future implementation when vendors catch up with the spec: + // var t = this.matrix; + // ctx.transform(t.xx, t.yx, t.xy, t.yy, t.dx, t.dy); + } + }, + _renderShape: function(/* Object */ ctx){ + // nothing + }, + _renderFill: function(/* Object */ ctx, /* Boolean */ apply){ + if("canvasFill" in this){ + if("canvasFillImage" in this){ + this.canvasFill = ctx.createPattern(this.canvasFillImage, "repeat"); + delete this.canvasFillImage; + } + ctx.fillStyle = this.canvasFill; + if(apply){ ctx.fill(); } + }else{ + ctx.fillStyle = "rgba(0,0,0,0.0)"; + } + }, + _renderStroke: function(/* Object */ ctx, /* Boolean */ apply){ + var s = this.strokeStyle; + if(s){ + ctx.strokeStyle = s.color.toString(); + ctx.lineWidth = s.width; + ctx.lineCap = s.cap; + if(typeof s.join == "number"){ + ctx.lineJoin = "miter"; + ctx.miterLimit = s.join; + }else{ + ctx.lineJoin = s.join; + } + if(apply){ ctx.stroke(); } + }else if(!apply){ + ctx.strokeStyle = "rgba(0,0,0,0.0)"; + } + }, + + // events are not implemented + getEventSource: function(){ return null; }, + connect: function(){}, + disconnect: function(){} + }); + + var modifyMethod = function(shape, method, extra){ + var old = shape.prototype[method]; + shape.prototype[method] = extra ? + function(){ + this.surface.makeDirty(); + old.apply(this, arguments); + extra.call(this); + return this; + } : + function(){ + this.surface.makeDirty(); + return old.apply(this, arguments); + }; + }; + + modifyMethod(g.Shape, "setTransform", + function(){ + // prepare Canvas-specific structures + if(this.matrix){ + this.canvasTransform = g.decompose(this.matrix); + }else{ + delete this.canvasTransform; + } + }); + + modifyMethod(g.Shape, "setFill", + function(){ + // prepare Canvas-specific structures + var fs = this.fillStyle, f; + if(fs){ + if(typeof(fs) == "object" && "type" in fs){ + var ctx = this.surface.rawNode.getContext("2d"); + switch(fs.type){ + case "linear": + case "radial": + f = fs.type == "linear" ? + ctx.createLinearGradient(fs.x1, fs.y1, fs.x2, fs.y2) : + ctx.createRadialGradient(fs.cx, fs.cy, 0, fs.cx, fs.cy, fs.r); + dojo.forEach(fs.colors, function(step){ + f.addColorStop(step.offset, g.normalizeColor(step.color).toString()); + }); + break; + case "pattern": + var img = new Image(fs.width, fs.height); + this.surface.downloadImage(img, fs.src); + this.canvasFillImage = img; + } + }else{ + // Set fill color using CSS RGBA func style + f = fs.toString(); + } + this.canvasFill = f; + }else{ + delete this.canvasFill; + } + }); + + modifyMethod(g.Shape, "setStroke"); + modifyMethod(g.Shape, "setShape"); + + dojo.declare("dojox.gfx.Group", g.Shape, { + // summary: a group shape (Canvas), which can be used + // to logically group shapes (e.g, to propagate matricies) + constructor: function(){ + gs.Container._init.call(this); + }, + _render: function(/* Object */ ctx){ + // summary: render the group + ctx.save(); + this._renderTransform(ctx); + this._renderFill(ctx); + this._renderStroke(ctx); + for(var i = 0; i < this.children.length; ++i){ + this.children[i]._render(ctx); + } + ctx.restore(); + } + }); + + dojo.declare("dojox.gfx.Rect", gs.Rect, { + // summary: a rectangle shape (Canvas) + _renderShape: function(/* Object */ ctx){ + var s = this.shape, r = Math.min(s.r, s.height / 2, s.width / 2), + xl = s.x, xr = xl + s.width, yt = s.y, yb = yt + s.height, + xl2 = xl + r, xr2 = xr - r, yt2 = yt + r, yb2 = yb - r; + ctx.beginPath(); + ctx.moveTo(xl2, yt); + if(r){ + ctx.arc(xr2, yt2, r, -halfPI, 0, false); + ctx.arc(xr2, yb2, r, 0, halfPI, false); + ctx.arc(xl2, yb2, r, halfPI, pi, false); + ctx.arc(xl2, yt2, r, pi, halfPI, false); + }else{ + ctx.lineTo(xr2, yt); + ctx.lineTo(xr, yb2); + ctx.lineTo(xl2, yb); + ctx.lineTo(xl, yt2); + } + ctx.closePath(); + } + }); + + var bezierCircle = []; + (function(){ + var u = ga.curvePI4; + bezierCircle.push(u.s, u.c1, u.c2, u.e); + for(var a = 45; a < 360; a += 45){ + var r = m.rotateg(a); + bezierCircle.push(mp(r, u.c1), mp(r, u.c2), mp(r, u.e)); + } + })(); + + dojo.declare("dojox.gfx.Ellipse", gs.Ellipse, { + // summary: an ellipse shape (Canvas) + setShape: function(){ + g.Ellipse.superclass.setShape.apply(this, arguments); + // prepare Canvas-specific structures + var s = this.shape, t, c1, c2, r = [], + M = m.normalize([m.translate(s.cx, s.cy), m.scale(s.rx, s.ry)]); + t = mp(M, bezierCircle[0]); + r.push([t.x, t.y]); + for(var i = 1; i < bezierCircle.length; i += 3){ + c1 = mp(M, bezierCircle[i]); + c2 = mp(M, bezierCircle[i + 1]); + t = mp(M, bezierCircle[i + 2]); + r.push([c1.x, c1.y, c2.x, c2.y, t.x, t.y]); + } + this.canvasEllipse = r; + return this; + }, + _renderShape: function(/* Object */ ctx){ + var r = this.canvasEllipse; + ctx.beginPath(); + ctx.moveTo.apply(ctx, r[0]); + for(var i = 1; i < r.length; ++i){ + ctx.bezierCurveTo.apply(ctx, r[i]); + } + ctx.closePath(); + } + }); + + dojo.declare("dojox.gfx.Circle", gs.Circle, { + // summary: a circle shape (Canvas) + _renderShape: function(/* Object */ ctx){ + var s = this.shape; + ctx.beginPath(); + ctx.arc(s.cx, s.cy, s.r, 0, twoPI, 1); + } + }); + + dojo.declare("dojox.gfx.Line", gs.Line, { + // summary: a line shape (Canvas) + _renderShape: function(/* Object */ ctx){ + var s = this.shape; + ctx.beginPath(); + ctx.moveTo(s.x1, s.y1); + ctx.lineTo(s.x2, s.y2); + } + }); + + dojo.declare("dojox.gfx.Polyline", gs.Polyline, { + // summary: a polyline/polygon shape (Canvas) + setShape: function(){ + g.Polyline.superclass.setShape.apply(this, arguments); + // dojo.inherited("setShape", arguments); + // prepare Canvas-specific structures + var p = this.shape.points, f = p[0], r = [], c, i; + if(p.length){ + if(typeof f == "number"){ + r.push(f, p[1]); + i = 2; + }else{ + r.push(f.x, f.y); + i = 1; + } + for(; i < p.length; ++i){ + c = p[i]; + if(typeof c == "number"){ + r.push(c, p[++i]); + }else{ + r.push(c.x, c.y); + } + } + } + this.canvasPolyline = r; + return this; + }, + _renderShape: function(/* Object */ ctx){ + // console.debug("Polyline::_renderShape"); + var p = this.canvasPolyline; + if(p.length){ + ctx.beginPath(); + ctx.moveTo(p[0], p[1]); + for(var i = 2; i < p.length; i += 2){ + ctx.lineTo(p[i], p[i + 1]); + } + } + } + }); + + dojo.declare("dojox.gfx.Image", gs.Image, { + // summary: an image shape (Canvas) + setShape: function(){ + g.Image.superclass.setShape.apply(this, arguments); + // prepare Canvas-specific structures + var img = new Image(); + this.surface.downloadImage(img, this.shape.src); + this.canvasImage = img; + return this; + }, + _renderShape: function(/* Object */ ctx){ + var s = this.shape; + ctx.drawImage(this.canvasImage, s.x, s.y, s.width, s.height); + } + }); + + dojo.declare("dojox.gfx.Text", gs.Text, { + // summary: a text shape (Canvas) + _renderShape: function(/* Object */ ctx){ + var s = this.shape; + // nothing for the moment + } + }); + modifyMethod(g.Text, "setFont"); + + var pathRenderers = { + M: "_moveToA", m: "_moveToR", + L: "_lineToA", l: "_lineToR", + H: "_hLineToA", h: "_hLineToR", + V: "_vLineToA", v: "_vLineToR", + C: "_curveToA", c: "_curveToR", + S: "_smoothCurveToA", s: "_smoothCurveToR", + Q: "_qCurveToA", q: "_qCurveToR", + T: "_qSmoothCurveToA", t: "_qSmoothCurveToR", + A: "_arcTo", a: "_arcTo", + Z: "_closePath", z: "_closePath" + }; + + dojo.declare("dojox.gfx.Path", g.path.Path, { + // summary: a path shape (Canvas) + constructor: function(){ + this.last = {}; + this.lastControl = {}; + }, + setShape: function(){ + this.canvasPath = []; + return g.Path.superclass.setShape.apply(this, arguments); + }, + _updateWithSegment: function(segment){ + var last = dojo.clone(this.last); + this[pathRenderers[segment.action]](this.canvasPath, segment.action, segment.args); + this.last = last; + g.Path.superclass._updateWithSegment.apply(this, arguments); + }, + _renderShape: function(/* Object */ ctx){ + var r = this.canvasPath; + ctx.beginPath(); + for(var i = 0; i < r.length; i += 2){ + ctx[r[i]].apply(ctx, r[i + 1]); + } + }, + _moveToA: function(result, action, args){ + result.push("moveTo", [args[0], args[1]]); + for(var i = 2; i < args.length; i += 2){ + result.push("lineTo", [args[i], args[i + 1]]); + } + this.last.x = args[args.length - 2]; + this.last.y = args[args.length - 1]; + this.lastControl = {}; + }, + _moveToR: function(result, action, args){ + if("x" in this.last){ + result.push("moveTo", [this.last.x += args[0], this.last.y += args[1]]); + }else{ + result.push("moveTo", [this.last.x = args[0], this.last.y = args[1]]); + } + for(var i = 2; i < args.length; i += 2){ + result.push("lineTo", [this.last.x += args[i], this.last.y += args[i + 1]]); + } + this.lastControl = {}; + }, + _lineToA: function(result, action, args){ + for(var i = 0; i < args.length; i += 2){ + result.push("lineTo", [args[i], args[i + 1]]); + } + this.last.x = args[args.length - 2]; + this.last.y = args[args.length - 1]; + this.lastControl = {}; + }, + _lineToR: function(result, action, args){ + for(var i = 0; i < args.length; i += 2){ + result.push("lineTo", [this.last.x += args[i], this.last.y += args[i + 1]]); + } + this.lastControl = {}; + }, + _hLineToA: function(result, action, args){ + for(var i = 0; i < args.length; ++i){ + result.push("lineTo", [args[i], this.last.y]); + } + this.last.x = args[args.length - 1]; + this.lastControl = {}; + }, + _hLineToR: function(result, action, args){ + for(var i = 0; i < args.length; ++i){ + result.push("lineTo", [this.last.x += args[i], this.last.y]); + } + this.lastControl = {}; + }, + _vLineToA: function(result, action, args){ + for(var i = 0; i < args.length; ++i){ + result.push("lineTo", [this.last.x, args[i]]); + } + this.last.y = args[args.length - 1]; + this.lastControl = {}; + }, + _vLineToR: function(result, action, args){ + for(var i = 0; i < args.length; ++i){ + result.push("lineTo", [this.last.x, this.last.y += args[i]]); + } + this.lastControl = {}; + }, + _curveToA: function(result, action, args){ + for(var i = 0; i < args.length; i += 6){ + result.push("bezierCurveTo", args.slice(i, i + 6)); + } + this.last.x = args[args.length - 2]; + this.last.y = args[args.length - 1]; + this.lastControl.x = args[args.length - 4]; + this.lastControl.y = args[args.length - 3]; + this.lastControl.type = "C"; + }, + _curveToR: function(result, action, args){ + for(var i = 0; i < args.length; i += 6){ + result.push("bezierCurveTo", [ + this.last.x + args[i], + this.last.y + args[i + 1], + this.lastControl.x = this.last.x + args[i + 2], + this.lastControl.y = this.last.y + args[i + 3], + this.last.x + args[i + 4], + this.last.y + args[i + 5] + ]); + this.last.x += args[i + 4]; + this.last.y += args[i + 5]; + } + this.lastControl.type = "C"; + }, + _smoothCurveToA: function(result, action, args){ + for(var i = 0; i < args.length; i += 4){ + var valid = this.lastControl.type == "C"; + result.push("bezierCurveTo", [ + valid ? 2 * this.last.x - this.lastControl.x : this.last.x, + valid ? 2 * this.last.y - this.lastControl.y : this.last.y, + args[i], + args[i + 1], + args[i + 2], + args[i + 3] + ]); + this.lastControl.x = args[i]; + this.lastControl.y = args[i + 1]; + this.lastControl.type = "C"; + } + this.last.x = args[args.length - 2]; + this.last.y = args[args.length - 1]; + }, + _smoothCurveToR: function(result, action, args){ + for(var i = 0; i < args.length; i += 4){ + var valid = this.lastControl.type == "C"; + result.push("bezierCurveTo", [ + valid ? 2 * this.last.x - this.lastControl.x : this.last.x, + valid ? 2 * this.last.y - this.lastControl.y : this.last.y, + this.last.x + args[i], + this.last.y + args[i + 1], + this.last.x + args[i + 2], + this.last.y + args[i + 3] + ]); + this.lastControl.x = this.last.x + args[i]; + this.lastControl.y = this.last.y + args[i + 1]; + this.lastControl.type = "C"; + this.last.x += args[i + 2]; + this.last.y += args[i + 3]; + } + }, + _qCurveToA: function(result, action, args){ + for(var i = 0; i < args.length; i += 4){ + result.push("quadraticCurveTo", args.slice(i, i + 4)); + } + this.last.x = args[args.length - 2]; + this.last.y = args[args.length - 1]; + this.lastControl.x = args[args.length - 4]; + this.lastControl.y = args[args.length - 3]; + this.lastControl.type = "Q"; + }, + _qCurveToR: function(result, action, args){ + for(var i = 0; i < args.length; i += 4){ + result.push("quadraticCurveTo", [ + this.lastControl.x = this.last.x + args[i], + this.lastControl.y = this.last.y + args[i + 1], + this.last.x + args[i + 2], + this.last.y + args[i + 3] + ]); + this.last.x += args[i + 2]; + this.last.y += args[i + 3]; + } + this.lastControl.type = "Q"; + }, + _qSmoothCurveToA: function(result, action, args){ + for(var i = 0; i < args.length; i += 2){ + var valid = this.lastControl.type == "Q"; + result.push("quadraticCurveTo", [ + this.lastControl.x = valid ? 2 * this.last.x - this.lastControl.x : this.last.x, + this.lastControl.y = valid ? 2 * this.last.y - this.lastControl.y : this.last.y, + args[i], + args[i + 1] + ]); + this.lastControl.type = "Q"; + } + this.last.x = args[args.length - 2]; + this.last.y = args[args.length - 1]; + }, + _qSmoothCurveToR: function(result, action, args){ + for(var i = 0; i < args.length; i += 2){ + var valid = this.lastControl.type == "Q"; + result.push("quadraticCurveTo", [ + this.lastControl.x = valid ? 2 * this.last.x - this.lastControl.x : this.last.x, + this.lastControl.y = valid ? 2 * this.last.y - this.lastControl.y : this.last.y, + this.last.x + args[i], + this.last.y + args[i + 1] + ]); + this.lastControl.type = "Q"; + this.last.x += args[i]; + this.last.y += args[i + 1]; + } + }, + _arcTo: function(result, action, args){ + var relative = action == "a"; + for(var i = 0; i < args.length; i += 7){ + var x1 = args[i + 5], y1 = args[i + 6]; + if(relative){ + x1 += this.last.x; + y1 += this.last.y; + } + var arcs = ga.arcAsBezier( + this.last, args[i], args[i + 1], args[i + 2], + args[i + 3] ? 1 : 0, args[i + 4] ? 1 : 0, + x1, y1 + ); + dojo.forEach(arcs, function(p){ + result.push("bezierCurveTo", p); + }); + this.last.x = x1; + this.last.y = y1; + } + this.lastControl = {}; + }, + _closePath: function(result, action, args){ + result.push("closePath", []); + this.lastControl = {}; + } + }); + dojo.forEach(["moveTo", "lineTo", "hLineTo", "vLineTo", "curveTo", + "smoothCurveTo", "qCurveTo", "qSmoothCurveTo", "arcTo", "closePath"], + function(method){ modifyMethod(g.Path, method); } + ); + + dojo.declare("dojox.gfx.TextPath", g.path.TextPath, { + // summary: a text shape (Canvas) + _renderShape: function(/* Object */ ctx){ + var s = this.shape; + // nothing for the moment + } + }); + + dojo.declare("dojox.gfx.Surface", gs.Surface, { + // summary: a surface object to be used for drawings (Canvas) + constructor: function(){ + gs.Container._init.call(this); + this.pendingImageCount = 0; + this.makeDirty(); + }, + setDimensions: function(width, height){ + // summary: sets the width and height of the rawNode + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + this.width = g.normalizedLength(width); // in pixels + this.height = g.normalizedLength(height); // in pixels + if(!this.rawNode) return this; + this.rawNode.width = width; + this.rawNode.height = height; + this.makeDirty(); + return this; // self + }, + getDimensions: function(){ + // summary: returns an object with properties "width" and "height" + return this.rawNode ? {width: this.rawNode.width, height: this.rawNode.height} : null; // Object + }, + _render: function(){ + // summary: render the all shapes + if(this.pendingImageCount){ return; } + var ctx = this.rawNode.getContext("2d"); + ctx.save(); + ctx.clearRect(0, 0, this.rawNode.width, this.rawNode.height); + for(var i = 0; i < this.children.length; ++i){ + this.children[i]._render(ctx); + } + ctx.restore(); + if("pendingRender" in this){ + clearTimeout(this.pendingRender); + delete this.pendingRender; + } + }, + makeDirty: function(){ + // summary: internal method, which is called when we may need to redraw + if(!this.pendingImagesCount && !("pendingRender" in this)){ + this.pendingRender = setTimeout(dojo.hitch(this, this._render), 0); + } + }, + downloadImage: function(img, url){ + // summary: + // internal method, which starts an image download and renders, when it is ready + // img: Image: + // the image object + // url: String: + // the url of the image + var handler = dojo.hitch(this, this.onImageLoad); + if(!this.pendingImageCount++ && "pendingRender" in this){ + clearTimeout(this.pendingRender); + delete this.pendingRender; + } + img.onload = handler; + img.onerror = handler; + img.onabort = handler; + img.src = url; + }, + onImageLoad: function(){ + if(!--this.pendingImageCount){ this._render(); } + }, + + // events are not implemented + getEventSource: function(){ return null; }, + connect: function(){}, + disconnect: function(){} + }); + + g.createSurface = function(parentNode, width, height){ + // summary: creates a surface (Canvas) + // parentNode: Node: a parent node + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + + if(!width){ width = "100%"; } + if(!height){ height = "100%"; } + var s = new g.Surface(), + p = dojo.byId(parentNode), + c = p.ownerDocument.createElement("canvas"); + c.width = width; + c.height = height; + p.appendChild(c); + s.rawNode = c; + s.surface = s; + return s; // dojox.gfx.Surface + }; + + // Extenders + + var C = gs.Container, Container = { + add: function(shape){ + this.surface.makeDirty(); + return C.add.apply(this, arguments); + }, + remove: function(shape, silently){ + this.surface.makeDirty(); + return C.remove.apply(this, arguments); + }, + clear: function(){ + this.surface.makeDirty(); + return C.clear.apply(this, arguments); + }, + _moveChildToFront: function(shape){ + this.surface.makeDirty(); + return C._moveChildToFront.apply(this, arguments); + }, + _moveChildToBack: function(shape){ + this.surface.makeDirty(); + return C._moveChildToBack.apply(this, arguments); + } + }; + + dojo.mixin(gs.Creator, { + // summary: Canvas shape creators + createObject: function(shapeType, rawShape) { + // summary: creates an instance of the passed shapeType class + // shapeType: Function: a class constructor to create an instance of + // rawShape: Object: properties to be passed in to the classes "setShape" method + // overrideSize: Boolean: set the size explicitly, if true + var shape = new shapeType(); + shape.surface = this.surface; + shape.setShape(rawShape); + this.add(shape); + return shape; // dojox.gfx.Shape + } + }); + + dojo.extend(g.Group, Container); + dojo.extend(g.Group, gs.Creator); + + dojo.extend(g.Surface, Container); + dojo.extend(g.Surface, gs.Creator); +})(); + +} diff --git a/includes/js/dojox/gfx/canvas_attach.js b/includes/js/dojox/gfx/canvas_attach.js new file mode 100644 index 0000000..82ccd13 --- /dev/null +++ b/includes/js/dojox/gfx/canvas_attach.js @@ -0,0 +1,8 @@ +dojo.require("dojox.gfx.canvas"); + +dojo.experimental("dojox.gfx.canvas_attach"); + +// not implemented +dojox.gfx.attachNode = function(){ + return null; // for now +}; diff --git a/includes/js/dojox/gfx/decompose.js b/includes/js/dojox/gfx/decompose.js new file mode 100644 index 0000000..4e34ee6 --- /dev/null +++ b/includes/js/dojox/gfx/decompose.js @@ -0,0 +1,139 @@ +if(!dojo._hasResource["dojox.gfx.decompose"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.decompose"] = true; +dojo.provide("dojox.gfx.decompose"); + +dojo.require("dojox.gfx.matrix"); + +(function(){ + var m = dojox.gfx.matrix; + + var eq = function(/* Number */ a, /* Number */ b){ + // summary: compare two FP numbers for equality + return Math.abs(a - b) <= 1e-6 * (Math.abs(a) + Math.abs(b)); // Boolean + }; + + var calcFromValues = function(/* Number */ r1, /* Number */ m1, /* Number */ r2, /* Number */ m2){ + // summary: uses two close FP ration and their original magnitudes to approximate the result + if(!isFinite(r1)){ + return r2; // Number + }else if(!isFinite(r2)){ + return r1; // Number + } + m1 = Math.abs(m1), m2 = Math.abs(m2); + return (m1 * r1 + m2 * r2) / (m1 + m2); // Number + }; + + var transpose = function(/* dojox.gfx.matrix.Matrix2D */ matrix){ + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object + var M = new m.Matrix2D(matrix); + return dojo.mixin(M, {dx: 0, dy: 0, xy: M.yx, yx: M.xy}); // dojox.gfx.matrix.Matrix2D + }; + + var scaleSign = function(/* dojox.gfx.matrix.Matrix2D */ matrix){ + return (matrix.xx * matrix.yy < 0 || matrix.xy * matrix.yx > 0) ? -1 : 1; // Number + }; + + var eigenvalueDecomposition = function(/* dojox.gfx.matrix.Matrix2D */ matrix){ + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object + var M = m.normalize(matrix), + b = -M.xx - M.yy, + c = M.xx * M.yy - M.xy * M.yx, + d = Math.sqrt(b * b - 4 * c), + l1 = -(b + (b < 0 ? -d : d)) / 2, + l2 = c / l1, + vx1 = M.xy / (l1 - M.xx), vy1 = 1, + vx2 = M.xy / (l2 - M.xx), vy2 = 1; + if(eq(l1, l2)){ + vx1 = 1, vy1 = 0, vx2 = 0, vy2 = 1; + } + if(!isFinite(vx1)){ + vx1 = 1, vy1 = (l1 - M.xx) / M.xy; + if(!isFinite(vy1)){ + vx1 = (l1 - M.yy) / M.yx, vy1 = 1; + if(!isFinite(vx1)){ + vx1 = 1, vy1 = M.yx / (l1 - M.yy); + } + } + } + if(!isFinite(vx2)){ + vx2 = 1, vy2 = (l2 - M.xx) / M.xy; + if(!isFinite(vy2)){ + vx2 = (l2 - M.yy) / M.yx, vy2 = 1; + if(!isFinite(vx2)){ + vx2 = 1, vy2 = M.yx / (l2 - M.yy); + } + } + } + var d1 = Math.sqrt(vx1 * vx1 + vy1 * vy1), + d2 = Math.sqrt(vx2 * vx2 + vy2 * vy2); + if(!isFinite(vx1 /= d1)){ vx1 = 0; } + if(!isFinite(vy1 /= d1)){ vy1 = 0; } + if(!isFinite(vx2 /= d2)){ vx2 = 0; } + if(!isFinite(vy2 /= d2)){ vy2 = 0; } + return { // Object + value1: l1, + value2: l2, + vector1: {x: vx1, y: vy1}, + vector2: {x: vx2, y: vy2} + }; + }; + + var decomposeSR = function(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){ + // summary: decomposes a matrix into [scale, rotate]; no checks are done. + var sign = scaleSign(M), + a = result.angle1 = (Math.atan2(M.yx, M.yy) + Math.atan2(-sign * M.xy, sign * M.xx)) / 2, + cos = Math.cos(a), sin = Math.sin(a); + result.sx = calcFromValues(M.xx / cos, cos, -M.xy / sin, sin); + result.sy = calcFromValues(M.yy / cos, cos, M.yx / sin, sin); + return result; // Object + }; + + var decomposeRS = function(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){ + // summary: decomposes a matrix into [rotate, scale]; no checks are done + var sign = scaleSign(M), + a = result.angle2 = (Math.atan2(sign * M.yx, sign * M.xx) + Math.atan2(-M.xy, M.yy)) / 2, + cos = Math.cos(a), sin = Math.sin(a); + result.sx = calcFromValues(M.xx / cos, cos, M.yx / sin, sin); + result.sy = calcFromValues(M.yy / cos, cos, -M.xy / sin, sin); + return result; // Object + }; + + dojox.gfx.decompose = function(matrix){ + // summary: decompose a 2D matrix into translation, scaling, and rotation components + // description: this function decompose a matrix into four logical components: + // translation, rotation, scaling, and one more rotation using SVD. + // The components should be applied in following order: + // | [translate, rotate(angle2), scale, rotate(angle1)] + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object + var M = m.normalize(matrix), + result = {dx: M.dx, dy: M.dy, sx: 1, sy: 1, angle1: 0, angle2: 0}; + // detect case: [scale] + if(eq(M.xy, 0) && eq(M.yx, 0)){ + return dojo.mixin(result, {sx: M.xx, sy: M.yy}); // Object + } + // detect case: [scale, rotate] + if(eq(M.xx * M.yx, -M.xy * M.yy)){ + return decomposeSR(M, result); // Object + } + // detect case: [rotate, scale] + if(eq(M.xx * M.xy, -M.yx * M.yy)){ + return decomposeRS(M, result); // Object + } + // do SVD + var MT = transpose(M), + u = eigenvalueDecomposition([M, MT]), + v = eigenvalueDecomposition([MT, M]), + U = new m.Matrix2D({xx: u.vector1.x, xy: u.vector2.x, yx: u.vector1.y, yy: u.vector2.y}), + VT = new m.Matrix2D({xx: v.vector1.x, xy: v.vector1.y, yx: v.vector2.x, yy: v.vector2.y}), + S = new m.Matrix2D([m.invert(U), M, m.invert(VT)]); + decomposeSR(VT, result); + S.xx *= result.sx; + S.yy *= result.sy; + decomposeRS(U, result); + S.xx *= result.sx; + S.yy *= result.sy; + return dojo.mixin(result, {sx: S.xx, sy: S.yy}); // Object + }; +})(); + +} diff --git a/includes/js/dojox/gfx/demos/beautify.html b/includes/js/dojox/gfx/demos/beautify.html new file mode 100644 index 0000000..d1f02f5 --- /dev/null +++ b/includes/js/dojox/gfx/demos/beautify.html @@ -0,0 +1,48 @@ + + +Beautify JSON + + + + + + +

Beautify JSON

+

Paste valid JSON in this textarea and receive a pretty-printed version of it. Use Firefox, if you want to be able to read comma-ended sequences (Python style). + Additionally it knows how to remove extra spaces from path elements.

+

+

+     Process "path" elements +     Pretty-print JSON

+

This program is a companion for inspector.html.

+ + diff --git a/includes/js/dojox/gfx/demos/butterfly.html b/includes/js/dojox/gfx/demos/butterfly.html new file mode 100644 index 0000000..2b9f188 --- /dev/null +++ b/includes/js/dojox/gfx/demos/butterfly.html @@ -0,0 +1,88 @@ + + +dojox.gfx: Butterfly + + + + + + + + +

dojox.gfx: Butterfly

+

This example was directly converted from SVG file.

+

This is a slightly modified version of a sample that shipped with JASC's WebDraw (www.jasc.com). Generated by Jasc WebDraw PR4(tm) on 06/07/01 12:18:39.

+ + + + + +
Rotation (0)
+
+
+
+
+
+
Scaling (1.000)
+
+
+
+
+
+
+ + diff --git a/includes/js/dojox/gfx/demos/career_test.html b/includes/js/dojox/gfx/demos/career_test.html new file mode 100644 index 0000000..3958395 --- /dev/null +++ b/includes/js/dojox/gfx/demos/career_test.html @@ -0,0 +1,467 @@ + + +dojox.gfx: Career Aptitude Test + + + + + + + + + + + + + +

dojox.gfx: Career Aptitude Test

+

Warning: Canvas renderer doesn't implement event handling.

+ +
+

Thank you for your interest in "I can't believe it's manure" Eateries™ +and for submitting your resume for our review. While this is an automated response, +please be assured that every resume is reviewed by us, and forwarded to the hiring +managers if the skills fit our needs.

+

In order order to evaluate your skills we ask you to take a career aptitude test. +You will have an exciting chance to operate one of our state-of-the-art workstations +remotely. Don't forget: +

+
    +
  1. Fish out a live speciment of dung-42 from the container.
  2. +
  3. Freeze it until you see an orange glow to kill the elements and make it less green.
  4. +
  5. Broil it until you see the orange glow again, and drop it on the table below.
  6. +
  7. You have to process all items without wasting resources and in minimal time.
  8. +
+

Warnings: don't overfreeze, don't overheat, don't drop the speciment, don't change the sequence, +don't touch the speciment in heating and freezing chambers until it is's ready.

+

Use your head and your mouse!

+

Please select the desired position:

+ + + + + + + + + + + + + +
Workstation Supervisor 
Shift Director 
Vice President #49653 
+
+ + + + + + + diff --git a/includes/js/dojox/gfx/demos/circles.html b/includes/js/dojox/gfx/demos/circles.html new file mode 100644 index 0000000..ce4d0cd --- /dev/null +++ b/includes/js/dojox/gfx/demos/circles.html @@ -0,0 +1,90 @@ + + +dojox.gfx: 100 draggable circles + + + + + + + + + + +

dojox.gfx: 100 draggable circles

+

Warning: Canvas renderer doesn't implement event handling.

+
+ + diff --git a/includes/js/dojox/gfx/demos/clock.html b/includes/js/dojox/gfx/demos/clock.html new file mode 100644 index 0000000..8d4d8c1 --- /dev/null +++ b/includes/js/dojox/gfx/demos/clock.html @@ -0,0 +1,253 @@ + + +dojox.gfx: interactive analog clock + + + + + + + + +

dojox.gfx: interactive analog clock

+

Grab hands and set your own time.

+

Warning: Canvas renderer doesn't implement event handling.

+
+

Current time: .

+

+ + diff --git a/includes/js/dojox/gfx/demos/clockWidget.html b/includes/js/dojox/gfx/demos/clockWidget.html new file mode 100644 index 0000000..409523c --- /dev/null +++ b/includes/js/dojox/gfx/demos/clockWidget.html @@ -0,0 +1,332 @@ + + +dojox.gfx: interactive analog clock + + + + + + + + +

dojox.gfx: interactive analog clock

+

Grab hands and set your own time.

+

Warning: Canvas renderer doesn't implement event handling.

+ + + +
+ +
+
+
+
+ +
+ + + + + + diff --git a/includes/js/dojox/gfx/demos/clock_black.html b/includes/js/dojox/gfx/demos/clock_black.html new file mode 100644 index 0000000..4c72770 --- /dev/null +++ b/includes/js/dojox/gfx/demos/clock_black.html @@ -0,0 +1,253 @@ + + +dojox.gfx: interactive analog clock + + + + + + + + +

dojox.gfx: interactive analog clock

+

Grab hands and set your own time.

+

Warning: Canvas renderer doesn't implement event handling.

+
+

Current time: .

+

+ + diff --git a/includes/js/dojox/gfx/demos/creator.html b/includes/js/dojox/gfx/demos/creator.html new file mode 100644 index 0000000..48ddf5b --- /dev/null +++ b/includes/js/dojox/gfx/demos/creator.html @@ -0,0 +1,123 @@ + + +Create DojoX GFX JSON + + + + + + + +

Create DojoX GFX JSON

+

This is a helper file, which serves as a template to generate static pictures.

+ + + + +
+
+
+
+

+

+     

+ + diff --git a/includes/js/dojox/gfx/demos/data/Lars.json b/includes/js/dojox/gfx/demos/data/Lars.json new file mode 100644 index 0000000..320feb0 --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/Lars.json @@ -0,0 +1,1823 @@ +[ + { + "name": "torso", + "children": [ + { + "name": "leftArm", + "shape": { + "type": "path", + "path": "M156.007,292.674c2.737,1.779,5.563,3.322,8.752,3.947c7.098,1.39,19.25-5.666,23.136-11.699 c1.572-2.441,8.077-21.031,11.177-14.271c1.224,2.67-1.59,4-1.399,6.462c3.108-1.425,5.48-5.242,8.918-2.182 c0.672,4.019-4.472,4.343-3.918,7.669c1.376,0.218,5.394-1.595,6.285-0.535c1.707,2.027-2.933,3.561-4.072,4.018 c-1.852,0.741-4.294,1.233-5.988,2.369c-2.636,1.768-4.766,5.143-7.034,7.4c-11.657,11.604-26.183,10.553-40.646,5.515 c-4.713-1.642-17.399-4.472-18.655-9.427c-1.647-6.502,5.523-7.999,10.184-6.74C147.658,286.528,151.725,289.891,156.007,292.674z" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "leftArmThumb", + "shape": { + "type": "path", + "path": "M188.257,284.902c-1.932-1.391-3.314-4.206-3.506-6.494c-0.149-1.786,0.59-6.522,3.199-3.95c0.792,0.78,0.083,2.155,0.558,2.943 c0.885,1.47,1.071,0.493,2.748,1.002c1.406,0.426,3.827,2.05,4.251,3.499" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "rightArm", + "shape": { + "type": "path", + "path": "M57.05,283.306c-5.502,5.354-13.185,8.541-18.249,14.221c-4.303,4.827-7.721,11.575-11.138,17.112 c-6.752,10.939-10.794,26.076-19.912,35.185c-3.869,3.866-7.637,5.721-7.251,12.032c0.932,0.372,1.548,0.589,2.418,0.683 c0.605-2.746,2.569-4.199,5.362-3.799c-0.14,3.365-3.512,5.941-3.228,9.235c0.364,4.223,3.983,5.968,7.181,2.662 c2.61-2.699,0.192-7.848,3.338-10.179c5.535-4.103,2.889,2.998,4.13,5.514c5.19,10.519,8.634-1.859,7.35-7.996 c-2.336-11.159-3.003-15.126,3.267-24.416c6.358-9.419,12.194-18.708,19.399-27.588c1.116-1.375,2.08-2.728,3.333-4" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "shirt", + "children": [ + { + "name": "tShirt", + "shape": { + "type": "path", + "path": "M96.509,268.264 c-2.301,0.323-4.69,0.205-6.945,0.72c-2.234,0.509-4.5,0.8-6.749,1.249c-4.369,0.872-8.206,3.265-12.3,5.024 c-3.259,1.401-6.644,2.571-9.763,4.26c-1.923,1.041-3.688,2.616-5.487,3.97c-1.543,1.16-3.495,2.11-4.854,3.562 c-2.205,2.354,0.896,7.408,1.854,9.873c0.92,2.368,2.149,4.82,2.749,7.29c0.228,0.937,0.235,2.058,0.875,2.873 c0.644,0.821,0.64,0.735,1.822,0.048c1.513-0.878,2.873-1.993,4.329-2.993c2.431-1.67,5.462-2.848,7.434-5.111 c-3.335,1.652-5.335,4.679-6.931,8.012c-1.398,2.92-4.482,35.854-5.389,38.947c-0.195,0.003-0.775,0.003-0.749,0.013 c20.561,0,41.123-0.07,61.684,0c2.1,0.007,3.607-0.497,5.529-1.252c0.715-0.281,2.257-0.356,2.807-0.745 c1.412-0.998-0.094-3.916-0.646-5.302c-1.425-3.579-2.111-37.767-4.726-40.543c1.842,0.057,4.127,1.311,5.937,1.95 c1.351,0.478,2.633,1.092,3.956,1.66c1.39,0.597,3.667,1.927,5.168,1.858c0.296-1.873,1.045-3.286,1.839-5.02 c0.943-2.061,1.155-4.214,1.528-6.415c0.351-2.07,0.898-3.787,1.939-5.635c0.531-0.942,1.356-1.73,1.693-2.768 c-0.443-0.402-1.043-0.907-1.603-1.125c-0.56-0.219-1.292-0.111-1.908-0.33c-1.237-0.438-2.44-1.089-3.669-1.576 c-3.773-1.499-7.519-2.983-11.319-4.466c-3.575-1.396-6.977-3.239-10.784-3.872c-1.735-0.289-3.467-0.529-5.073-0.906" + }, + "fill": "#4459A5", + "stroke": { + "color": "#000000", + "cap": "round" + } + }, + { + "name": "shirtNeck", + "shape": { + "type": "path", + "path": "M99.759,268.889 c-0.984,0.152-1.746-0.549-2.75-0.5c-1.369,0.066-1.649,0.872-2.153,2c-1.037,2.325-2.442,4.974,0.064,6.946 c2.53,1.991,6.964,1.717,9.829,0.803c1.616-0.516,3.045-1.24,3.825-2.867c0.508-1.061,0.935-2.771,0.149-3.598 c-0.231-0.243-0.562-0.376-0.84-0.534" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round" + } + }, + { + "name": "shirtLogo", + "children": [ + { + "children": [ + { + "shape": { + "type": "path", + "path": "M104.864,296.92c-0.151-0.003,7.101,0.41,7.052,0.404c0.132,0.028-0.172,0.633-0.021,0.632 c-0.226,0.028-7.244-0.454-7.28-0.464C104.657,297.518,104.776,296.904,104.864,296.92z" + }, + "stroke": { + } + } + ] + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M90.071,295.919c-0.199,0.004,6.792,0.43,6.79,0.446c0.153,0.005-0.031,0.663,0.012,0.665 c0.272,0.015-6.79-0.471-6.875-0.459C89.881,296.56,89.796,295.899,90.071,295.919z" + }, + "stroke": { + } + } + ] + }, + { + "shape": { + "type": "path", + "path": "M84.407,306.476c0.2-0.159,0.322-1.04,0.254,0.057 c-0.542-0.356-2.02,2.083-4.215,2.001c-1.887-1.706-4.559-3.384-4.302-7.092c0.652-2.599,3.082-4.084,5.213-3.942 c1.889,0.377,2.899,0.716,4,1.318c-0.497,0.957-0.175,0.866-0.459,0.703c0.456-2.398,0.598-5.75,0.312-7.855 c0.594-0.554,0.714,0.125,1.249,0.941c0.502-0.727,0.509-1.425,0.875-0.571c-0.207,1.328-0.809,7.186-0.711,10.174 c-0.126,2.797-0.375,4.354-0.051,4.985c-0.718,0.613-0.667,1.006-0.981,1.381c-0.72-1.33-1.056-0.132-1.339-0.157 C84.632,308.442,84.493,305.791,84.407,306.476z M81.186,307.176c2.403,0.206,3.734-2.164,3.841-4.222 c0.269-2.72-0.896-5.104-3.198-5.04c-1.972,0.437-3.46,2.188-3.331,4.638C78.171,306.265,79.847,306.961,81.186,307.176z" + }, + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M93.321,297.766c2.592,0.148,5.688,2.315,5.696,5.627 c-0.611,4.576-3.69,5.316-6.158,5.581c-2.68-0.76-5.708-1.872-5.413-6.472C88.086,299.394,90.653,297.875,93.321,297.766z M92.939,307.46c2.531,0.735,3.706-1.297,3.666-3.935c0.114-2.219-0.641-4.584-3.389-4.896c-2.29-0.552-3.366,2.188-3.661,4.688 C89.339,305.264,89.934,307.95,92.939,307.46z" + }, + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M99.688,303.916c0.03-1.511,0.055-4.731,0.022-4.646 c0.481-1.355,0.658-0.556,1.034-1.297c0.263,1.473,0.653,0.326,1.186,0.066c-0.386,2.517-0.513,3.347-0.574,4.949 c-0.068-0.47-0.128,2.28-0.238,2.188c-0.055,1.935-0.036,2.201-0.047,4.219c-0.079,0.914-0.28,2.412-1.126,3.831 c-0.61,1.212-1.73,1.146-3.24,1.651c0.073-0.945-0.065-1.242-0.096-1.822c0.098,0.138,0.213,0.604,0.225,0.398 c1.892,0.228,2.209-1.896,2.362-3.366c0.042,0.304,0.512-6.933,0.415-7.061C99.73,302.636,99.75,303.178,99.688,303.916z M100.978,295.564c0.717,0.14,1.11,0.61,1.099,1.156c0.052,0.552-0.595,0.993-1.286,1.015c-0.541-0.074-1.025-0.548-1.022-1.054 C99.813,296.084,100.292,295.643,100.978,295.564z" + }, + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M108.115,298.791c3.028-0.067,5.283,1.359,5.256,5.757 c-0.264,3.479-3.366,4.63-5.883,5.12c-2.429-0.034-5.619-2.241-5.16-5.811C102.322,300.085,105.715,298.845,108.115,298.791z M107.351,309.232c2.675-0.132,3.839-2.333,3.841-4.497c0.246-2.344-0.263-4.833-2.923-5.396 c-2.844,0.299-3.974,1.917-4.053,4.48C104.136,306.655,104.854,308.372,107.351,309.232z" + }, + "stroke": { + } + } + ] + } + ] + } + ] + }, + { + "name": "heads", + "children": [ + { + "name": "head1", + "children": [ + { + "name": "leftEart", + "children": [ + { + "shape": { + "type": "path", + "path": "M201.557,195.474 c7.734-4.547,16.591-5.012,18.405,4.443c2.43,12.659-3.317,13.328-14.598,13.328" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M211.711,203.09 c0.523,0.004,0.946-0.208,1.27-0.635" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M211.076,197.377 c3.062,3.013,5.489,5.624,4.443,10.155" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + }, + { + "name": "bgHairTop", + "shape": { + "type": "path", + "path": "M54.384,199.306c-5.253-4.402-7.511-11.061-15.779-10.632c3.449-1.277,7.116-2.397,10.911-2.666 c-2.873-1.397-5.865-2.575-8.231-4.718c3.986-1.119,11.47-1.817,14.864,0.75c-5.183-2.758-8.397-7.816-13.062-10.598 c6.014-0.643,12.377,0.978,18.022,2.265c-2.547-4.486-6.682-10.83-10.523-14.297c5.033,1.052,10.647,4.518,15.062,7.177 c-1.614-4.176-5.634-8.406-7.859-12.513c10.312-1.125,12.522,4.919,19.7,9.932c-0.412-0.127-1.114-0.113-1.527,0.015 c0.875-7.261,3.058-12.8,8.258-18.566c6.771-7.507,17.812-9.131,24.095-15.381c-4.699,1.821-4.518,23.765-4.875,28.955" + }, + "fill": "#FFF471", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "bgHairLeft", + "shape": { + "type": "path", + "path": "M92.384,243.972c-6.334,7.929-12.601,12.241-22.465,15.362c3.65-1.263,7.735-5.86,7.695-9.928 c-2.208,0.218-4.49,0.605-6.498,1.097c1.244-1.097,2.087-3.239,3.198-4.396c-5.77,0.001-12.131,1.133-18.396,1.23 c5.013-2.809,10.665-3.25,12.398-9.246c-3.59,0.313-7.233,1.606-11.033,1.097c1.731-2.022,3.953-3.995,5.049-6.447 c-3.781,0.056-6.665,3.098-10.547,2.465c0.962-2.863,3.187-5.208,4.531-7.766c-5.59-0.273-11.658,2.45-17.732,2.564 c5.494-2.857,8.967-7.819,12.3-12.718c5.233-7.693,10.625-9.96,20.349-9.981c11.059-0.024,15.558,6.714,20.984,16 c2.786,4.767,7.249,14.375,0.832,18" + }, + "fill": "#FFF471", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "bgHair", + "shape": { + "type": "path", + "path": "M142.384,255.306c2.984,6.076,3.567,11.856,10.531,14.6c-0.134-3.114-0.094-6.664,1.619-9.033 c1.605,1.968,3.122,4.211,5.048,5.698c-0.29-1.769,0.412-4.024,0.233-5.828c3.445,0.26,4.979,3.965,8.468,4.479 c0.066-2.78,0.427-5.151,0.868-7.813c2.687,0.2,4.768,1.565,7.132,2.997c0.452-4.921-0.409-10.579-0.667-15.666 c-5.795-0.756-12.291,2.827-17.899,3.899c-4.414,0.844-14.136,0.524-15.333,6" + }, + "fill": "#FFF471", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "neck", + "shape": { + "type": "path", + "path": "M106.989,254.499c-2.932,6.063-4.613,11.997-8.947,17.137c7.288,10.195,16.311-10.9,15.183-17.026 c-1.926-1.138-3.928-1.589-6.236-1.38" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "headShape", + "shape": { + "type": "path", + "path": "M210.941,207.665c-0.843,3.985-2.081,7.982-3.769,11.783c-3.374,7.604-8.543,14.427-16.052,18.899 c-2.94,2.13-5.983,4.167-9.109,6.085c-25.013,15.342-55.353,23.08-82.254,10.57c-3.433-1.557-6.785-3.431-10.053-5.66 c-1.821-1.184-3.592-2.46-5.308-3.832c-1.715-1.373-3.375-2.842-4.972-4.412c-2.352-2.148-4.576-4.425-6.631-6.814 c-6.168-7.169-10.823-15.358-12.87-24.185c-0.649-3.284-0.84-6.634-0.5-9.975c4.48-13.743,14.22-24.364,26.109-32.149 c2.973-1.946,6.079-3.715,9.271-5.309c30.581-15.027,69.581-10.027,95.851,12.209c2.564,2.254,4.988,4.651,7.244,7.178 c4.513,5.054,8.354,10.626,11.312,16.64C210.178,201.505,210.798,204.496,210.941,207.665z" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "rightEar", + "children": [ + { + "shape": { + "type": "path", + "path": "M64.857,195.606 c-6.59-7.181-15.047-10.664-19.467,3.676c-1.235,4.007-1.87,14.468,1.29,17.786c4.223,4.435,13.591,0.529,19.055-0.015" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M52.407,196.743 c-1.702,3.613-1.257,7.505-1.27,11.424" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M51.772,209.437 c-3.39-4.661,0.922-5.769,5.078-6.347" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + }, + { + "name": "fgHair", + "shape": { + "type": "path", + "path": "M90.384,154.639c8.453-11.353,15.678-13.458,28.581-15.915c-1.382,3.376-3.89,7.352-5.179,11.16 c5.01-1.816,9.571-6.545,15.218-8.413c11.355-3.755,23.852-1.903,35.671-2.213c-3.004,3.712-4.912,7.88-2.026,11.447 c5.856-2.212,13.37-6.871,19.635-6.646c0.263,4.561-0.024,9.278,0.201,13.841c3.509-1.201,6.015-3.04,8.277-5.148 s3.761-4.049,4.942-5.2c1.063,2.408,2.134,5.334,2.24,8.494c-0.182,3.462-0.866,6.794-2.66,9.291 c3.663,0.65,6.098-2.021,8.35-4.479c-0.655,4.349-3.164,8.604-3.851,13.013c2.178-0.072,4.382,0.216,6.367-0.48 c-1.389,3.093-3.069,7.287-6.616,8.414c-4.475,1.423-4.354-0.992-7.315-4.332c-4.892-5.518-9.774-6.791-15.872-9.464 c-6.585-2.887-10.983-6.47-17.963-8.219c-8.994-2.255-19.864-3.867-28.093-5.196c2.466,1.967,1.138,5.594,0.659,8.625 c-2.729-0.645-4.41-3.813-6.301-5.158c0.953,3.195,0.983,6.953-2.134,8.491c-6.145-5.226-9.199-9.721-17.527-11.647 c1,1.83,1.728,4.208,1.396,6.402c-0.751,4.971-0.289,3.134-3.836,2.466c-5.192-0.977-9.953-3.677-15.815-4.496 c3.292,2.002,5.469,5.017,7.418,8.21c-2.651,0.404-6.238,0.257-8.382,1.671c2.456,0.38,3.44,2.166,3.197,4.714 c-7.45,0.386-13.623,0.731-19.915,5.434" + }, + "fill": "#FFF471", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + } + ] + }, + { + "name": "eyes", + "children": [ + { + "name": "eyes1", + "children": [ + { + "shape": { + "type": "path", + "path": "M123.163,176.668 c-5.066,1.17-9.01,7.888-13.666,10.335c-4.238,2.227-8.648,6.636-7.009,12.332c1.971,6.848,12.042,3.991,16.261,1.165 c5.282-3.539,9.59-8.517,12.006-14.524c1.523-3.787,2.568-7.272-1.509-9.391c-2.905-1.51-8.174-1.386-11.417-0.583" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M182.545,179.865 c-3.533,0.169-4.854-1.166-8.408-0.001c-3,0.983-6.24,1.936-8.852,3.743c-3.938,2.725-7.46,5.555-4.73,13.592 c1.973,5.811,8.791,7.571,14.656,6.667c5.537-0.854,9.078-4.977,11.408-10.007c3.666-7.918,0.943-11.639-6.742-13.659" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000", + "cap": "round" + } + }, + { + "shape": { + "type": "path", + "path": "M108.829,183.668c-1.308-1.03-4.557,0.011-5.6-1.733 c-1.056-1.765,1.735-5.409,2.984-6.192c5.684-3.562,15.946-0.39,19.95-6.742" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M163.877,167.198c2.369,1.282,6.539,0.307,9.408,0.815 c3.449,0.612,7.066,2.657,10.592,2.851" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M127.496,192.002c-4.917-2.12-9.188-1.708-8.608,4.942 c3.132,1.734,5.428-2.82,7.275-4.942" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M174.852,203.143c-0.293,0.12-0.307,0.577-0.943,0.282 c-1.605-3.188-0.404-6.507,2.676-8.192c2.15-1.176,5.67-1.759,7.471,0.359c0.199,0.234,0.412,0.521,0.514,0.813 c0.229,0.649-0.285,0.95-0.285,0.95s-3.988,6.009-3.285,1.934c0.438,1.743-5.537,5.743-2.287,1.653 c-1.955,2.583-2.525,1.977-3.859,2.868" + }, + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "eyes2", + "children": [ + { + "shape": { + "type": "path", + "path": "M98.668,186.108c0.668-8.915,15.545-13.749,22.667-15" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M169.667,178.108 c5.307,3.436,16.928,5.632,19.668,12.333" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M105.334,197.775c8.085-4.283,17.059-2.8,25-6.333" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M164.001,198.775c4.656-0.417,9.664,1.805,14.334,2.017 c3.951,0.18,5.773,0.189,9,2.316" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M124.001,188.108c3.039-0.258,4.594,2.571,5.301,4.983 c-1.096,1.242-2.065,2.646-2.968,4.017" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M168.335,194.108c-1.77,2.293-4.869,3.271-6.299,5.91 c1.377,0.991,3.02,2.122,3.965,3.424" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + } + ] + }, + { + "name": "beard", + "children": [ + { + "shape": { + "type": "path", + "path": "M96.05,213.639 c-0.366,0.21-0.783,0.389-1.167,0.5" + }, + "fill": "#AFA8A5", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M102.55,211.972 c0.314-0.01,0.554-0.198,0.667-0.5" + }, + "fill": "#AFA8A5", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M105.717,208.805 c0.164-0.109,0.336-0.224,0.5-0.333" + }, + "fill": "#AFA8A5", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M111.05,207.972 c-0.651-1.81,0.859-2.262,2.333-1.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M117.717,209.805 c1.738,0,3.653,0.369,5.333,0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M132.717,214.472 c0.104-0.21,0.162-0.435,0.167-0.667" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M139.551,216.972 c0.215-0.175,0.465-0.426,0.666-0.667" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M144.551,213.305 c0.277-0.056,0.556-0.111,0.833-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M147.884,216.639 c0.195,0.045,0.369-0.013,0.5-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M148.384,214.139 c0.112-0.168,0.222-0.332,0.333-0.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M98.217,219.305c1.697-1.772,4.233-2.109,5.967-4.046c1.519-1.696,3.812-3.001,4.2-5.454" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M152.717,216.139 c0.611,0,1.223,0,1.834,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M160.384,217.472 c0.333,0,0.667,0,1,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M163.217,215.972 c0.321-0.042,0.658-0.175,0.834-0.333" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M164.217,218.805 c0.167,0,0.333,0,0.5,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M168.384,217.972 c0.056-0.056,0.111-0.111,0.167-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M169.884,225.805 c0.491-0.397,0.882-0.926,1.167-1.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M172.717,221.972 c0.056,0,0.111,0,0.167,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M171.717,229.805 c0.334,0.075,0.659,0.025,0.834-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M190.051,227.805 c0.163-0.242,0.398-0.423,0.666-0.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M197.384,221.472 c0.258-0.007,0.485-0.125,0.667-0.333" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M199.384,214.972 c-0.04-0.333,0.075-0.609,0.333-0.833" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M117.884,257.305 c0.056,0,0.111,0,0.167,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M142.717,252.472 c0.358,0.069,0.71,0.016,1-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M137.884,256.472 c0.277,0,0.556,0,0.833,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M160.884,252.972 c0.366-0.138,0.765-0.402,1-0.667" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M171.384,250.139 c0.235-0.263,0.475-0.561,0.667-0.834" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M89.384,243.972 c0.537,0.378,1.329,0.876,1.833,1.333" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M79.05,225.472 c0.087,0.272,0.143,0.55,0.167,0.833" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M73.884,222.639 c0,0.167,0,0.333,0,0.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M72.55,219.805c0.466-0.325,0.875-0.797,1.167-1.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M71.717,211.972c0.422-0.553,0.776-1.305,1-2" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M78.55,214.472c0-0.111,0-0.222,0-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M79.384,218.805c-0.001-0.137,0.055-0.248,0.167-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M80.217,221.139c0.111,0,0.222,0,0.333,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M75.55,226.472c0.103-0.5,0.156-0.977,0.167-1.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M78.55,230.139c0.111,0,0.222,0,0.333,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M83.384,227.639c0.118-0.059,0.215-0.107,0.333-0.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M81.55,237.139c0.056,0,0.111,0,0.167,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M86.217,233.805c0.056,0,0.111,0,0.167,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M87.884,230.472c0.595-0.181,1.219-0.527,1.833-0.667" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M88.717,222.139 c-0.929,2.359-1.615,4.865-2.667,7.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M89.05,216.139 c0.784-0.736,1.709-1.565,2.833-1.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M94.217,210.139 c1.599-0.089,3.199-0.167,4.833-0.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M94.884,224.639 c0.052-0.588-0.004-1.155-0.167-1.667" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M92.384,228.305 c0.585-0.062,1.244-0.132,1.667-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M88.717,240.139 c0.111,0,0.222,0,0.333,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M95.884,243.305 c0.526,0.1,1.017-0.015,1.333-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M98.55,248.305 c0.069-0.24,0.265-0.926,0.333-1.166" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M96.55,249.805 c0.125,0.014,0.18-0.042,0.167-0.166" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M104.55,250.139 c0.01-0.238,0.126-0.428,0.333-0.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M106.884,251.972 c0.195,0.045,0.37-0.013,0.5-0.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M113.884,254.805 c0.758-0.586,1.595-1.171,2.382-1.774c0.072,0.376,0.418,0.685,0.48,1.079c0.833,0.265,1.624-0.021,1.638-0.971" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M122.217,254.639 c0.063-0.165,0.179-0.288,0.333-0.334" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M125.884,255.805 c1.13-0.745,2.783-0.962,3.667-2" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M132.217,255.972 c0.638-0.492,1.104-1.173,1.141-1.975c-1.11,0.062-1.449-0.888-1.475-1.858" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M129.717,249.305 c-0.045,0.154-0.168,0.271-0.333,0.334" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M136.551,252.305 c0.222,0,0.444,0,0.666,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M110.217,251.305 c0.056-0.056,0.111-0.11,0.167-0.166" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M140.717,251.805 c0.111,0,0.223,0,0.334,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M150.051,249.472 c0.111,0,0.222,0,0.333,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M143.217,255.472 c1.022-0.313,1.724-1.175,2.646-1.654c0.203,0.321,0.44,0.626,0.521,0.987" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M152.217,253.472 c0.165-0.063,0.288-0.179,0.334-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M155.051,254.639 c0.222,0,0.444,0,0.666,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M157.717,256.472 c0.326-0.027,0.546-0.073,0.834-0.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M163.217,252.639 c0.552-0.891,2.082-1.512,2.341-2.334c0.37-1.177-1.156-3.069-1.007-4.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M167.384,235.972 c0.118-0.54,0.353-1.064,0.667-1.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M170.717,242.805 c0-0.333,0-0.667,0-1" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M170.217,236.972 c0-0.333,0-0.667,0-1" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M179.051,235.805 c0.378-0.101,0.738-0.35,1-0.667" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M185.051,232.805 c0.379-0.319,0.656-0.702,0.833-1.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M188.051,231.139 c0.063-0.39,0.178-0.792,0.333-1.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M197.884,223.305 c-0.166,0.277-0.334,0.556-0.5,0.833" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + }, + { + "name": "mouths", + "children": [ + { + "name": "mouth1", + "children": [ + { + "shape": { + "type": "path", + "path": "M177.122,216.821c-0.515,2.282-5.213,3.21-7.433,3.854 c-3.254,0.945-6.596,1.345-9.895,1.851c-3.26,0.5-6.665,0.671-10.107,0.671c-3.596,0-6.645,0.559-10.107,0.671 c-3.105,0.1-6.898-0.474-9.694-1.3c-3.527-1.043-6.672-1.666-10.096-3.062c-2.823-1.152-5.746-1.876-8.462-3.143 c-2.594-1.209-6.084-1.994-8.221-3.552c-1.068,1.834-5.867,3.748-8.1,4.546c-2.444,0.874-8.881,2.725-7.817,5.512 c0.457,1.195,1.948,2.273,2.63,3.385c0.774,1.261,1.139,2.601,2.057,3.859c1.83,2.5,4.506,4.773,6,7.34 c1.308,2.249,2.096,4.74,4.01,6.67c2.214,2.233,5.792,2.634,9.231,2.399c7.028-0.479,13.982-2.129,20.481-3.983 c3.295-0.941,6.699-1.536,10.087-2.686c3.272-1.111,6.641-3,9.402-4.777c5.248-3.377,10.278-6.409,14.283-10.705 c1.479-1.587,3.429-2.503,5.15-3.859" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M135.25,241.319 c0.723-4.757-10.487-8.47-14.898-9.526c-3.09-0.74-6.68-1.17-9.858-1.712c-2.758-0.47-6.865-0.836-9.437,0.369 c-1.385,0.649-2.843,1.724-4.141,2.513c2.156,3.964,4.728,8.861,9.468,11.506c3.229,1.801,5.511,0.777,8.859,0.373 c3.045-0.369,6.046-0.703,9.029-1.72c3.479-1.186,7.228-2.385,10.978-2.475" + }, + "fill": "#FFC0C0", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M148.656,225.547c1.267,0.697,1.301,2.838,0.671,3.9 c-0.702,1.182-2.063,1.4-3.306,2.01c-2.271,1.116-4.581,2.624-7.482,2.638c-4.619,0.023-2.143-4.067-0.253-5.869 c2.405-2.292,5.057-2.72,8.72-2.512c0.588,0.034,1.095,0.041,1.65,0.168" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M130.299,223.365 c2.687,0.437,5.619,4.384,3.727,6.422c-1.234,1.33-7.94,1.391-9.915,1.296c-4.896-0.233-2.502-2.445-0.613-4.525 c1.604-1.767,5.088-3.249,7.833-3.36" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M113.178,217.157 c2.56,0.958,4.922,5.057,5.352,7.215c0.377,1.885-0.324,2.106-2.526,2.643c-1.366,0.333-3.636,0.723-5.105,0.385 c-2.506-0.577-5.883-5.051-4.909-7.223c1.03-2.298,5.944-2.923,8.427-2.852" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M99.359,217.661 c2.038,0.432,4.015,4.279,2.468,5.625c-1.083,0.943-5.221,1.795-6.799,1.589c-4.032-0.526-2.265-4.102-0.866-5.872 c0.706-0.894,1.049-1.976,2.514-2.186c1.627-0.233,2.501,0.99,3.921,1.346" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M181.815,222.895c-3.101-2.75-4.764-8.777-9.282-10.403" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "mouth2", + "children": [ + { + "shape": { + "type": "path", + "path": "M87.57,221.951c5.563-1.759,11.066-1.32,16.694-1.782c2.93-0.24,5.228-1.14,8.309-0.927c3.142,0.217,6.085-0.235,9.289,0.176 c7.136,0.914,13.96,0.598,21.112,1.506c3.654,0.464,7.218,0.609,10.81,0.869c4.017,0.291,7.646,1.582,11.433,2.623 c2.948,0.812,6.347,1.618,9.011,2.99c2.521,1.298,6.354,2.856,8.3,4.72c-2.775,0.027-5.601,2.603-8.021,3.769 c-2.93,1.412-5.741,2.949-8.656,4.432c-5.599,2.849-11.885,5.468-18.104,6.53c-6.793,1.161-13.195,2.107-20.067,2.197 c-7.699,0.102-14.313-4.705-20.735-8.396c-2.071-1.19-4.69-2.182-6.504-3.666c-1.792-1.466-3.469-3.386-5.154-4.984 c-2.703-2.564-7.519-5.649-8.13-9.438" + }, + "stroke": { + "color": "#000000", + "width": "3", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M87.785,228.193 c-5.907-3.235-0.344-9.531,3.971-11.424" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2" + } + }, + { + "shape": { + "type": "path", + "path": "M184.679,227.228c-1.534,2.583-2.548,5.334-4.025,7.889" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M106.862,219.528 c-3.071-0.74-5.608,2.166-6.318,4.738c-0.379,1.375-0.494,2.55,0.748,3.337c1.519,0.962,2.905-0.052,4.418-0.332 c2.518-0.467,7.293,0.053,6.461-4.248c-0.568-2.938-3.743-3.682-6.338-3.335c-0.451,0.06-0.758,0.212-1.205,0.229" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M119.764,218.479 c-2.648,1.243-4.657,3.518-5.346,6.377c-0.866,3.594,3.9,3.711,6.356,2.865c2.64-0.91,4.77-3.351,3.299-6.133 c-1.01-1.91-3.979-2.548-6.026-2.823" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M130.388,219.492 c-1.753,1.382-4.069,4.525-4.835,6.61c-1.159,3.156,2.296,3.371,4.868,3.348c3.061-0.028,6.6-1.148,5.022-4.78 c-1.168-2.691-2.552-4.85-5.551-5.241" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M142.954,221.087 c-1.502,0.337-5.418,3.249-5.638,4.997c-0.292,2.311,4.856,4.536,6.854,4.234c2.503-0.377,4.384-3.175,3.167-5.65 c-0.92-1.873-3.36-2.252-4.508-3.932" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M155.354,222.663 c-2.039,0.426-4.212,2.287-4.766,4.444c-0.723,2.821,3.225,3.383,5.458,3.331c2.541-0.059,5.126-1.752,3.249-4.32 c-1.394-1.908-3.707-3.189-5.304-4.636" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M168.367,237.924 c-1.554-1.217-3.302-2.557-5.203-2.976c-2.973-0.654-3.537,2.131-3.377,4.406c0.205,2.913,1.032,3.883,3.901,2.344 c1.988-1.066,4.272-1.997,4.599-4.456" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M151.524,246.202 c-1.912-0.166-4.003-4.491-2.91-6.25c0.771-1.239,5.456-1.688,6.858-1.292c0.271,0.917,0.979,1.841,0.829,2.771 c-0.088,0.54-0.994,1.645-1.296,2.188c-1.08,1.951-2.133,1.866-3.998,2.684" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M145.911,241.457 c-0.209,1.649-0.215,2.702-1.528,3.801c-0.885,0.739-1.773,1.19-2.54,2.1c-0.786,0.933-1.226,2.38-2.792,1.812 c-1.042-0.377-1.959-2.318-2.138-3.311c-0.299-1.676-1.003-5.228,0.783-6.158c1.155-0.603,7.067-0.18,7.43,1.32" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M133.12,238.991 c-1.495-0.087-2.253-1.33-3.918-0.964c-1.42,0.311-2.489,1.354-2.54,2.836c-0.052,1.527,0.99,5.581,1.852,6.956 c2.363,3.771,4.329-1.535,5.516-3.159c1.117-1.526,2.643-2.053,2.271-3.958c-0.318-1.632-1.118-2.047-2.766-2.329 c-0.382-0.065-0.773-0.095-1.158-0.147" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M116.853,237.429 c-1.049,2.211-0.173,5.147,0.047,7.566c0.357,3.929,3.827,2.028,5.831,0.067c1.575-1.541,4.599-4.86,2.209-6.484 c-1.881-1.279-5.727-2.458-7.756-1.107" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M107.455,233.38 c-0.813,2.487-1.704,5.049,0.073,7.364c1.91,2.486,4.009,1.229,5.537-0.939c1.056-1.5,3.316-4.481,1.563-6.017 c-1.347-1.179-6.468-1.518-7.854-0.325" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "mouth3", + "children": [ + { + "shape": { + "type": "path", + "path": "M99.05,218.972 c1.691-0.875,3.313-2.39,4.833-3.537c1.231-0.928,2.782-1.671,3.5-3.072c1.846,3.486,7.661,4.669,11.003,6.067 c3.553,1.486,7.174,3.066,10.784,4.166c4.271,1.301,9.277,1.67,13.721,2.343c4.155,0.629,9.979,1.365,14.162,0.496 c1.181-0.245,2.343-1.024,3.462-1.446c0.162,1.905-3.637,3.023-4.933,3.487c-2.435,0.871-4.18,2.541-6.362,3.871 c-1.623,0.989-2.974,1.669-4.755,2.117c-1.77,0.445-3.353,0.806-4.825,1.878c-5.915,4.311-15.264,3.247-22.424,3.13 c-5.384-0.088-6.719-5.372-9.337-9c-1.437-1.991-2.843-3.854-3.796-6.138c-0.871-2.086-1.119-4.582-2.033-6.528" + }, + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M107.217,227.972 c1.182-2.033,4.375-2.176,6.5-1.963c2.879,0.289,4.124,1.217,6.168,3.167c1.834,1.749,5.906,5.509,5.64,8.271 c-2.808,0.89-7.847,0.402-10.346-1.104c-1.334-0.804-1.151-2.256-2.246-3.588c-0.712-0.866-1.836-2.673-2.855-3.311 c-0.209-0.94-2.106-1.499-3.028-1.805" + }, + "fill": "#F4BDBD", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + } + ] + }, + { + "name": "personalProps", + "children": [ + { + "name": "hat", + "children": [ + { + "children": [ + { + "children": [ + { + "shape": { + "type": "path", + "path": "M88.374,173.144c0.474-0.074,16.606,2.725,18.01,5.879 c1.145,2.572,28.184,4.568,28.184,4.568l35.971-5.618l5.025,1.132l7.211,0.315l9.295,0.851l10.188,3.248l5.75,2.935 l1.615-1.832l-0.264-5.27l-3.967-7.087c0,0-22.045-13.031-23.273-13.703c-1.229-0.669-4.941-2.294-6.484-4.542 c-8.584-12.528-8.404-18.05-3.371-6.461c0,0,2.662-7.592,2.52-8.575c-0.143-0.982,0.355-5.031,0.355-5.031l2.396-6.832 c0,0-1.379-5.341-2.738-7.19c-1.357-1.844-15.793-4.078-18.162-4.011c-24.933,0.706-3.783,0.071-25.567,0.724 c-24.317,0.728-0.882-2.591-24.068,3.551c-24.228,6.418-5.35-1.298-23.187,6.142c-18.301,7.633-16.67,7.186-16.704,10.685 c-0.034,3.499-3.057-4.884-0.034,3.499c3.023,8.381,3.037-3.871,3.023,8.381c-0.015,12.252,6.696,4.557,1.678,12.373 c-5.017,7.813-3.831,7.91-0.179,8.543c17.017,2.953,4.157,4.378,17.427,3.175" + }, + "fill": "#FF0000", + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M156.605,114.92l-13.936,0.381l-11.633,0.343c-10.646,0.319-11.973-0.155-12.021-0.175l-0.599-0.238 l-0.577,0.514l0.049-0.047c-0.118,0.09-1.43,0.957-11.145,3.53c-9.989,2.646-12.812,2.931-13.421,2.704 c-0.822-0.306-0.821-0.306-7.791,2.604l-2.104,0.878c-16.037,6.689-17.342,7.324-17.342,10.316c0,0.019,0.001,0.041,0.001,0.06 c-0.224-0.108-0.459-0.199-0.787-0.04c-0.357,0.173-0.565,0.275-0.565,0.672c0,0.557,0.411,1.697,1.399,4.438 c0.924,2.561,1.71,3.671,2.714,3.833c0.083,0.014,0.164,0.02,0.241,0.02c0.007,0.584,0.01,1.339,0.01,2.313 c0,0.561-0.001,1.902-0.001,1.916c0,6.908,2.176,8.105,3.347,8.749c0,0,0.075,0.045,0.151,0.09 c-0.095,0.332-0.47,1.1-1.661,2.955c-2.509,3.908-3.516,5.931-3.516,7.303c0,0.358,0.068,0.671,0.196,0.962 c0.544,1.237,1.926,1.477,3.677,1.78l0.135,0.023c8.138,1.412,9.14,2.422,9.568,2.854c0.923,0.931,1.511,0.928,7.224,0.413 c0.06,0.014,0.102,0.068,0.165,0.071c2.167,0.105,16.131,3.138,17.087,5.288c1.147,2.578,16.416,4.228,29.023,5.159 l0.115,0.009c0,0,35.523-5.548,35.896-5.606c0.345,0.078,4.927,1.11,4.927,1.11l7.3,0.319c0,0,8.927,0.818,9.139,0.837 c0.202,0.064,9.854,3.142,10.006,3.19c0.143,0.073,6.368,3.251,6.368,3.251l2.398-2.719l-0.296-5.911l-4.213-7.526 l-0.232-0.137c-0.9-0.532-22.073-13.047-23.303-13.72c-0.001,0-0.735-0.38-0.735-0.38c-1.48-0.752-4.238-2.151-5.404-3.85 c-1.357-1.982-2.451-3.729-3.355-5.268c0.022-0.064,0.104-0.296,0.104-0.296c1.193-3.402,2.576-7.619,2.576-8.885 c0-0.063-0.004-0.118-0.011-0.165c-0.012-0.083-0.017-0.204-0.017-0.356c0-0.909,0.194-2.911,0.363-4.307 c0.072-0.205,2.46-7.013,2.46-7.013l-0.076-0.294c-0.146-0.566-1.468-5.584-2.9-7.532 C173.721,116.784,158.242,114.874,156.605,114.92z M131.097,117.643l11.614-0.342l13.951-0.382 c2.575-0.073,16.104,2.238,17.336,3.614c0.956,1.3,2.058,4.938,2.49,6.549c-0.188,0.536-2.33,6.642-2.33,6.642l-0.013,0.107 c-0.073,0.592-0.387,3.224-0.387,4.658c0,0.258,0.011,0.477,0.034,0.639c-0.006,0.493-0.768,3.026-1.659,5.709 c-2.14-4.566-2.792-4.606-3.242-4.629l-0.62-0.031l-0.354,0.571c-0.069,0.124-0.102,0.29-0.102,0.492 c0,2.273,4.134,9.172,6.993,13.346c1.456,2.12,4.509,3.669,6.149,4.501l0.682,0.353c1.138,0.622,20.813,12.25,23.011,13.549 c0.239,0.427,3.513,6.275,3.721,6.647c0.02,0.393,0.199,3.971,0.231,4.629c-0.23,0.262-0.472,0.535-0.832,0.944 c-1.07-0.546-5.132-2.619-5.132-2.619l-10.369-3.306l-9.404-0.86c0,0-6.995-0.307-7.169-0.315 c-0.168-0.038-5.124-1.155-5.124-1.155s-35.814,5.594-36.044,5.63c-12.419-0.922-25.993-2.687-27.285-4.058 c-1.366-3.097-13.245-5.574-17.517-6.211c-0.203-0.212-0.479-0.346-0.793-0.318c-3.083,0.28-5.996,0.544-6.4,0.369 c0-0.003-0.12-0.117-0.12-0.117c-0.703-0.708-1.879-1.895-10.646-3.416l-0.135-0.023c-0.827-0.143-2.075-0.359-2.188-0.614 c-0.021-0.048-0.033-0.111-0.033-0.193c0-0.592,0.632-2.179,3.205-6.187c1.488-2.318,2.024-3.388,2.024-4.188 c0-0.15-0.019-0.291-0.054-0.428c-0.181-0.712-0.758-1.03-1.179-1.261c-0.865-0.476-2.311-1.271-2.311-6.993 c0-0.014,0.001-1.098,0.001-1.56c0-4.969-0.065-4.992-0.833-5.258c-0.424-0.146-0.816,0.001-1.178,0.377 c-0.208-0.289-0.558-0.898-1.073-2.324c-0.205-0.568-0.385-1.068-0.542-1.506c0.587-0.423,0.632-1.277,0.636-1.644 l-0.014-0.825c-0.004-0.119-0.007-0.231-0.007-0.338c0-1.702,0.899-2.264,16.109-8.608l2.105-0.878 c4.165-1.739,5.948-2.482,6.375-2.562c0.817,0.296,2.292,0.597,14.579-2.658c8.169-2.164,10.697-3.187,11.58-3.704 C120.451,117.773,124.529,117.84,131.097,117.643z" + }, + "stroke": { + } + } + ] + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M155.146,147.929c4.879-9.398-5.344-20.199-12.65-21.176 c-12.05-1.61-13.404,10.426-13.684,21.258c3.73,2.016,8.915,3.425,11.721,6.534" + }, + "fill": "#FFFFFF", + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M133.446,127.979c-4.599,3.921-5.426,11.933-5.635,20.006l-0.017,0.654l4.415,2.067 c2.849,1.244,5.793,2.529,7.581,4.509c0.371,0.41,1.004,0.442,1.412,0.072c0.219-0.197,0.33-0.469,0.33-0.743 c0-0.239-0.084-0.479-0.258-0.67c-2.076-2.299-5.222-3.673-8.266-5.001c0,0-2.377-1.112-3.174-1.486 c0.223-7.385,1.021-14.572,4.909-17.887c1.892-1.614,4.386-2.189,7.621-1.757c4.143,0.554,9.086,4.472,11.5,9.113 c1.348,2.591,2.51,6.535,0.395,10.611c-0.254,0.49-0.064,1.093,0.426,1.348c0.49,0.254,1.094,0.063,1.35-0.427 c1.959-3.775,1.818-8.199-0.395-12.456c-2.732-5.251-8.203-9.53-13.012-10.172C138.853,125.257,135.763,126,133.446,127.979z" + }, + "stroke": { + } + } + ] + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M154.077,146.278c-2.156,1.18-4.24,2.619-6.256,4.01c-3.635,2.509-7.068,4.878-10.941,5.924 c-2.991,0.808-6.055,1.058-9.3,1.324c-3.222,0.263-6.553,0.536-9.783,1.406c-2.027,0.546-4.117,1.397-6.137,2.221 c-3.491,1.423-7.102,2.895-10.528,2.866c-0.552-0.005-1.004,0.439-1.009,0.991s0.439,1.004,0.991,1.009 c3.828,0.033,7.627-1.516,11.301-3.014c2.054-0.837,3.994-1.628,5.902-2.142c3.054-0.823,6.292-1.088,9.425-1.344 c3.191-0.261,6.492-0.531,9.659-1.386c4.205-1.135,7.941-3.714,11.557-6.208c1.973-1.362,4.014-2.771,6.08-3.901 c0.484-0.265,0.662-0.873,0.396-1.357S154.562,146.013,154.077,146.278z" + }, + "stroke": { + } + } + ] + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M156.458,153.549c-2.619,0.064-5.709,0.812-8.98,1.604c-4.279,1.035-8.701,2.104-11.902,1.536 c-0.543-0.096-1.063,0.267-1.159,0.81c-0.097,0.544,0.267,1.063,0.81,1.16c3.613,0.641,8.24-0.481,12.72-1.562 c3.166-0.766,6.154-1.489,8.561-1.548c5.664-0.141,7.961,0.698,13.508,2.724c0.518,0.189,1.094-0.077,1.281-0.596 c0.189-0.519-0.076-1.091-0.596-1.282C165.069,154.337,162.501,153.399,156.458,153.549z" + }, + "stroke": { + } + } + ] + } + ] + } + ] + }, + { + "name": "textSurface", + "children": [ + { + "name": "spokenBubble", + "children": [ + { + "name": "textContainer", + "shape": { + "type": "path", + "path": "M225.719,45.306c0-6.627,5.373-12,12-12h181.333 c6.627,0,12,5.373,12,12V150.64c0,6.627-5.373,12-12,12H237.719c-6.627,0-12-5.373-12-12V45.306z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "name": "textArrowBelow", + "shape": { + "type": "path", + "path": "M249.052,160.639 c-0.775,14.251-1.676,18.525-9.1,30.565c9.705-0.79,21.952-21.605,25.1-30.045" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "thoughtBubble", + "children": [ + { + "name": "textContainer_1_", + "shape": { + "type": "path", + "path": "M202.698,21.089 c19.686-26.45,59.686-24.45,79.747-0.084c2.697,1.349,5.571,1.709,7.472,0.781c15.28-13.888,33.272-14.043,49.893-7.839 c2.771,1.034,5.478,2.219,8.031,3.421c28.543-21.729,75.543-10.729,83.166,27.658c0,0-1.324,3.889,1.165,6.603 c18.212,11.011,26.212,32.011,22.212,53.011c-1,5.333-3.223,9.667-6.037,13.52c-2.814,3.854-1.381,0-2.613-0.591 c-1.35-0.929-3.35-0.929-4.35-1.929c16,7,27,22,30,39c2,21-8,41-27,50c-16,7.5-32.5,5.5-45.745-2.556 c-2.532-1.384-4.229-1.856-5.336-1.551c-1.919,0.107-3.919,2.107-5.919,2.107c4-1,6-5,10-6c-15,11-35,12-52,3c-13-7-20-20-24-34 c1,5,3,9,3.299,13.505c-0.397,0.708-3.423,2.219-6.655,3.466c-22.627,8.729-49.423,1.729-65.241-19.971 c-3.453,0-6.263,0.589-8.723,0.879c-17.3,3.2-32.381-7.709-40.771-22.689c-1.678-2.996-3.089-6.153-4.195-9.396 c-15.714-7.795-29.714-18.795-33.714-37.795c-5-25,11-45,29.842-57.667c0.719-2.335,1.697-4.636,3.006-6.896 C201.159,23.306,202.698,21.089,202.698,21.089z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M269.719,186.306c0,4.602-4.179,8.333-9.333,8.333c-5.155,0-9.334-3.731-9.334-8.333 c0-4.603,4.179-8.333,9.334-8.333C265.54,177.973,269.719,181.704,269.719,186.306z" + }, + "fill": "#FFFFFF", + "stroke": { + } + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M269.719,186.306c0,4.602-4.179,8.333-9.333,8.333c-5.155,0-9.334-3.731-9.334-8.333 c0-4.603,4.179-8.333,9.334-8.333C265.54,177.973,269.719,181.704,269.719,186.306z" + }, + "fill": "none", + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M268.225,186.165c-0.564,8.736-13.982,9.286-15.633,0.853 c-1.785-9.125,15.017-10.254,15.649-0.451c0.125,1.929,3.078,1.388,2.955-0.521c-0.814-12.597-20.828-12.412-21.639,0.119 c-0.827,12.813,20.831,13.028,21.655,0.283C271.337,184.518,268.35,184.235,268.225,186.165z" + }, + "fill": "#FFFFFF", + "stroke": { + } + } + ] + } + ] + }, + { + "shape": { + "type": "path", + "path": "M260.386,188.306c0,3.498-2.985,6.333-6.667,6.333 s-6.667-2.835-6.667-6.333c0-3.498,2.985-6.333,6.667-6.333S260.386,184.808,260.386,188.306z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M238.386,196.973c0,1.289-1.045,2.333-2.334,2.333 c-1.288,0-2.333-1.045-2.333-2.333s1.045-2.333,2.333-2.333C237.341,194.639,238.386,195.684,238.386,196.973z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M285.719,179.973c0,4.602-4.253,8.333-9.5,8.333 s-9.5-3.731-9.5-8.333c0-4.603,4.253-8.333,9.5-8.333S285.719,175.371,285.719,179.973z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "yellBubble", + "children": [ + { + "shape": { + "type": "path", + "path": "M251.156,176.051 l40.228-15.992" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M280.932,149.385 l-40.667,36.42" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "textContainer_2_", + "shape": { + "type": "path", + "path": "M217.778,34.643 c8.609,6.684,9.952,3.684,7.987-5.785c6.308,5.125,9.308,3.782,10.188-4.309c2.433,8.091,5.266,8.091,9.12-1.703 c6.063,9.793,13.146,9.793,24.043,3.878c6.103,5.915,16.02,5.915,20.094-4.64c17.178,10.555,28.511,10.555,45.233-5.505 c5.941,16.06,17.273,16.06,18.835,1.458c19.688,14.603,29.605,14.603,46.749-17.802c-0.144,32.405,6.939,32.405,29.26,16.182 c-12.403,16.223-9.57,16.223,4.813,6.576c-11.07,9.646-8.07,10.99,4.333,9.089c-8.061,6.244-6.717,9.244,2.533,11.068 c-9.25,1.489-9.25,5.703-0.315,13.07c-8.935,6.115-8.935,15.385,7.513,10.932c-16.447,24.677-16.447,35.631,14.938,36.553 c-31.385,19.303-31.385,28.571-4.39,40.526c-26.995,1.528-26.995,5.741-5.942,17.857c-21.053-8.801-22.396-5.802-9.526,11.916 c-17.213-13.374-20.213-12.03-12.048,8.029c-11.479-20.06-14.312-20.06-10.553,3.532c-13.676-23.591-20.759-23.591-29.814-2.664 c-7.944-20.927-17.861-20.927-27.072,12.467c-12.039-33.395-23.373-33.395-23.148-1.581 c-22.89-31.814-34.224-31.814-61.517-8.479c6.042-23.335-3.874-23.335-11.9-9.703c-8.975-13.632-16.058-13.632-23.926,4.361 c-2.049-17.993-4.882-17.993-10.51-1.486c2.314-16.508-0.686-17.851-12.385-5.019c7.356-17.175,6.013-20.176-10.27-7.879 c16.283-15.61,16.283-19.824-9.255-12.972c25.538-20.334,25.538-29.603,1.919-46.578c23.619-3.249,23.619-14.204-0.313-25.522 c23.933-8.905,23.933-18.175,7.798-37.429C226.385,48.854,226.385,44.64,217.778,34.643z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + } + ] + } + ] + } +] \ No newline at end of file diff --git a/includes/js/dojox/gfx/demos/data/Lars.svg b/includes/js/dojox/gfx/demos/data/Lars.svg new file mode 100644 index 0000000..7295501 --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/Lars.svg @@ -0,0 +1,531 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/includes/js/dojox/gfx/demos/data/LarsDreaming.json b/includes/js/dojox/gfx/demos/data/LarsDreaming.json new file mode 100644 index 0000000..d4cd1ad --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/LarsDreaming.json @@ -0,0 +1,1823 @@ +[ + { + "name": "torso", + "children": [ + { + "name": "leftArm", + "shape": { + "type": "path", + "path": "M156.007,292.675c2.737,1.778,5.563,3.321,8.752,3.946c7.099,1.391,19.25-5.666,23.136-11.698 c1.572-2.441,8.077-21.031,11.178-14.271c1.224,2.67-1.59,4-1.399,6.462c3.108-1.425,5.48-5.242,8.918-2.182 c0.672,4.019-4.472,4.343-3.918,7.669c1.376,0.218,5.395-1.595,6.285-0.535c1.707,2.027-2.933,3.561-4.072,4.018 c-1.852,0.741-4.294,1.233-5.988,2.369c-2.636,1.769-4.766,5.144-7.033,7.4c-11.657,11.604-26.184,10.553-40.646,5.515 c-4.713-1.642-17.399-4.472-18.655-9.427c-1.647-6.502,5.523-7.999,10.184-6.74C147.658,286.528,151.725,289.892,156.007,292.675z" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "leftArmThumb", + "shape": { + "type": "path", + "path": "M188.257,284.902c-1.932-1.391-3.313-4.206-3.506-6.494c-0.149-1.786,0.59-6.521,3.199-3.95c0.792,0.78,0.083,2.155,0.558,2.943 c0.885,1.47,1.071,0.493,2.748,1.002c1.406,0.426,3.827,2.05,4.251,3.499" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "rightArm", + "shape": { + "type": "path", + "path": "M57.05,283.307c-5.502,5.354-13.185,8.541-18.249,14.221c-4.303,4.827-7.721,11.575-11.138,17.112 c-6.752,10.938-10.794,26.076-19.912,35.185c-3.869,3.866-7.637,5.722-7.251,12.032c0.932,0.372,1.548,0.589,2.418,0.683 c0.605-2.745,2.569-4.198,5.362-3.799c-0.14,3.365-3.512,5.941-3.228,9.235c0.364,4.223,3.983,5.968,7.181,2.662 c2.61-2.699,0.192-7.849,3.338-10.18c5.535-4.103,2.889,2.998,4.13,5.515c5.19,10.519,8.634-1.859,7.35-7.996 c-2.336-11.159-3.003-15.126,3.267-24.416c6.358-9.419,12.194-18.708,19.399-27.588c1.116-1.375,2.08-2.729,3.333-4" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "shirt", + "children": [ + { + "name": "tShirt", + "shape": { + "type": "path", + "path": "M96.509,268.265 c-2.301,0.323-4.69,0.205-6.945,0.72c-2.234,0.509-4.5,0.8-6.749,1.249c-4.369,0.872-8.206,3.265-12.3,5.024 c-3.259,1.4-6.644,2.57-9.763,4.26c-1.923,1.041-3.688,2.616-5.487,3.97c-1.543,1.16-3.495,2.11-4.854,3.563 c-2.205,2.354,0.896,7.407,1.854,9.873c0.92,2.367,2.149,4.819,2.749,7.29c0.228,0.937,0.235,2.058,0.875,2.872 c0.644,0.821,0.64,0.735,1.822,0.049c1.513-0.878,2.873-1.993,4.329-2.993c2.431-1.67,5.462-2.849,7.434-5.111 c-3.335,1.652-5.335,4.679-6.931,8.012c-1.398,2.921-4.482,35.854-5.389,38.947c-0.195,0.003-0.775,0.003-0.749,0.013 c20.561,0,41.123-0.069,61.684,0c2.1,0.008,3.607-0.496,5.529-1.252c0.715-0.28,2.257-0.355,2.807-0.744 c1.412-0.998-0.094-3.916-0.646-5.303c-1.425-3.579-2.111-37.767-4.726-40.543c1.842,0.058,4.127,1.312,5.938,1.95 c1.351,0.478,2.633,1.092,3.956,1.66c1.39,0.597,3.667,1.927,5.168,1.857c0.296-1.872,1.045-3.285,1.839-5.02 c0.942-2.061,1.155-4.214,1.528-6.415c0.351-2.07,0.897-3.787,1.938-5.635c0.531-0.942,1.356-1.73,1.693-2.769 c-0.443-0.401-1.043-0.906-1.604-1.125c-0.56-0.219-1.292-0.11-1.908-0.33c-1.236-0.438-2.439-1.089-3.668-1.575 c-3.773-1.499-7.519-2.983-11.319-4.467c-3.575-1.396-6.977-3.238-10.784-3.871c-1.735-0.289-3.467-0.529-5.073-0.906" + }, + "fill": "#4459A5", + "stroke": { + "color": "#000000", + "cap": "round" + } + }, + { + "name": "shirtNeck", + "shape": { + "type": "path", + "path": "M99.759,268.89 c-0.984,0.151-1.746-0.549-2.75-0.5c-1.369,0.065-1.649,0.872-2.153,2c-1.037,2.325-2.442,4.974,0.064,6.945 c2.53,1.991,6.964,1.718,9.829,0.804c1.616-0.517,3.045-1.24,3.825-2.867c0.508-1.062,0.935-2.771,0.149-3.598 c-0.231-0.243-0.562-0.376-0.84-0.534" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round" + } + }, + { + "name": "shirtLogo", + "children": [ + { + "children": [ + { + "shape": { + "type": "path", + "path": "M104.864,296.921c-0.151-0.004,7.101,0.409,7.052,0.403c0.132,0.028-0.172,0.633-0.021,0.632 c-0.226,0.028-7.244-0.454-7.28-0.464C104.657,297.519,104.776,296.904,104.864,296.921z" + }, + "stroke": { + } + } + ] + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M90.071,295.919c-0.199,0.005,6.792,0.431,6.79,0.446c0.153,0.005-0.031,0.663,0.012,0.665 c0.272,0.016-6.79-0.471-6.875-0.459C89.881,296.561,89.796,295.899,90.071,295.919z" + }, + "stroke": { + } + } + ] + }, + { + "shape": { + "type": "path", + "path": "M84.407,306.477c0.2-0.159,0.322-1.04,0.254,0.057c-0.542-0.355-2.02,2.083-4.215,2.001 c-1.887-1.706-4.559-3.384-4.302-7.092c0.652-2.599,3.082-4.084,5.213-3.942c1.889,0.378,2.899,0.717,4,1.318 c-0.497,0.957-0.175,0.866-0.459,0.703c0.456-2.398,0.598-5.75,0.312-7.855c0.594-0.554,0.714,0.125,1.249,0.941 c0.502-0.727,0.509-1.425,0.875-0.571c-0.207,1.328-0.809,7.187-0.711,10.174c-0.126,2.798-0.375,4.354-0.051,4.985 c-0.718,0.613-0.667,1.006-0.981,1.381c-0.72-1.33-1.056-0.132-1.339-0.157C84.632,308.442,84.493,305.791,84.407,306.477z M81.186,307.177c2.403,0.206,3.734-2.164,3.841-4.223c0.269-2.72-0.896-5.104-3.198-5.04c-1.972,0.438-3.46,2.188-3.331,4.639 C78.171,306.266,79.847,306.962,81.186,307.177z" + }, + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M93.321,297.767c2.592,0.147,5.688,2.314,5.696,5.627c-0.611,4.576-3.69,5.316-6.158,5.581 c-2.68-0.76-5.708-1.872-5.413-6.472C88.086,299.395,90.653,297.875,93.321,297.767z M92.939,307.46 c2.531,0.735,3.706-1.297,3.666-3.935c0.114-2.219-0.641-4.584-3.389-4.896c-2.29-0.553-3.366,2.188-3.661,4.688 C89.339,305.265,89.934,307.95,92.939,307.46z" + }, + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M99.688,303.916c0.03-1.511,0.055-4.73,0.022-4.646c0.481-1.355,0.658-0.556,1.034-1.297 c0.263,1.473,0.653,0.326,1.186,0.065c-0.386,2.518-0.513,3.348-0.574,4.949c-0.068-0.47-0.128,2.28-0.238,2.188 c-0.055,1.935-0.036,2.201-0.047,4.219c-0.079,0.914-0.28,2.412-1.126,3.831c-0.61,1.212-1.73,1.146-3.24,1.651 c0.073-0.945-0.065-1.242-0.096-1.822c0.098,0.138,0.213,0.604,0.225,0.397c1.892,0.229,2.209-1.896,2.362-3.365 c0.042,0.304,0.512-6.934,0.415-7.062C99.73,302.637,99.75,303.179,99.688,303.916z M100.978,295.564 c0.717,0.14,1.11,0.61,1.099,1.156c0.052,0.552-0.595,0.993-1.286,1.015c-0.541-0.074-1.025-0.548-1.022-1.054 C99.813,296.084,100.292,295.644,100.978,295.564z" + }, + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M108.115,298.791c3.028-0.066,5.283,1.359,5.256,5.758c-0.264,3.479-3.366,4.63-5.883,5.119 c-2.429-0.033-5.619-2.24-5.16-5.811C102.322,300.085,105.715,298.846,108.115,298.791z M107.351,309.232 c2.675-0.132,3.839-2.333,3.841-4.497c0.246-2.344-0.263-4.833-2.923-5.396c-2.844,0.299-3.974,1.917-4.053,4.479 C104.136,306.655,104.854,308.372,107.351,309.232z" + }, + "stroke": { + } + } + ] + } + ] + } + ] + }, + { + "name": "heads", + "children": [ + { + "name": "head1", + "children": [ + { + "name": "leftEart", + "children": [ + { + "shape": { + "type": "path", + "path": "M201.557,195.475 c7.734-4.547,16.592-5.012,18.405,4.443c2.43,12.659-3.317,13.328-14.598,13.328" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M211.711,203.09 c0.523,0.004,0.946-0.208,1.271-0.635" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M211.076,197.377 c3.062,3.013,5.489,5.624,4.442,10.155" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + }, + { + "name": "bgHairTop", + "shape": { + "type": "path", + "path": "M54.384,199.307c-5.253-4.402-7.511-11.061-15.779-10.632c3.449-1.277,7.116-2.397,10.911-2.666 c-2.873-1.397-5.865-2.575-8.231-4.718c3.986-1.119,11.47-1.817,14.864,0.75c-5.183-2.758-8.397-7.816-13.062-10.598 c6.014-0.643,12.377,0.978,18.022,2.265c-2.547-4.486-6.682-10.83-10.523-14.297c5.033,1.052,10.647,4.518,15.062,7.177 c-1.614-4.176-5.634-8.406-7.859-12.513c10.312-1.125,12.522,4.919,19.7,9.932c-0.412-0.127-1.114-0.113-1.527,0.015 c0.875-7.261,3.058-12.8,8.258-18.566c6.771-7.507,17.813-9.131,24.095-15.381c-4.699,1.821-4.518,23.765-4.875,28.955" + }, + "fill": "#FFF471", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "bgHairLeft", + "shape": { + "type": "path", + "path": "M92.384,243.973c-6.334,7.929-12.601,12.241-22.465,15.361c3.65-1.263,7.735-5.859,7.695-9.928 c-2.208,0.218-4.49,0.605-6.498,1.098c1.244-1.098,2.087-3.239,3.198-4.396c-5.77,0.001-12.131,1.133-18.396,1.23 c5.013-2.81,10.665-3.25,12.398-9.247c-3.59,0.313-7.233,1.606-11.033,1.097c1.731-2.022,3.953-3.995,5.049-6.447 c-3.781,0.056-6.665,3.098-10.547,2.465c0.962-2.863,3.187-5.208,4.531-7.766c-5.59-0.273-11.658,2.45-17.732,2.564 c5.494-2.857,8.967-7.819,12.3-12.718c5.233-7.693,10.625-9.96,20.349-9.981c11.059-0.024,15.558,6.714,20.984,16 c2.786,4.767,7.249,14.375,0.832,18" + }, + "fill": "#FFF471", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "bgHair", + "shape": { + "type": "path", + "path": "M142.384,255.307c2.984,6.076,3.567,11.855,10.531,14.6c-0.134-3.114-0.094-6.664,1.619-9.033 c1.604,1.969,3.122,4.211,5.048,5.698c-0.29-1.769,0.412-4.023,0.233-5.828c3.444,0.261,4.979,3.965,8.468,4.479 c0.065-2.78,0.427-5.151,0.868-7.813c2.687,0.2,4.768,1.565,7.132,2.997c0.452-4.921-0.409-10.579-0.667-15.666 c-5.795-0.756-12.291,2.827-17.899,3.899c-4.414,0.844-14.136,0.523-15.333,6" + }, + "fill": "#FFF471", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "neck", + "shape": { + "type": "path", + "path": "M106.989,254.499c-2.932,6.063-4.613,11.997-8.947,17.138c7.288,10.194,16.311-10.9,15.183-17.026 c-1.926-1.138-3.928-1.589-6.236-1.38" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "headShape", + "shape": { + "type": "path", + "path": "M210.941,207.666c-0.844,3.985-2.081,7.982-3.77,11.783c-3.374,7.604-8.543,14.427-16.052,18.899 c-2.94,2.13-5.983,4.167-9.109,6.085c-25.013,15.342-55.353,23.08-82.254,10.57c-3.433-1.558-6.785-3.432-10.053-5.66 c-1.821-1.185-3.592-2.46-5.308-3.832c-1.715-1.373-3.375-2.842-4.972-4.412c-2.352-2.148-4.576-4.425-6.631-6.814 c-6.168-7.169-10.823-15.358-12.87-24.185c-0.649-3.284-0.84-6.634-0.5-9.975c4.48-13.743,14.22-24.364,26.109-32.149 c2.973-1.946,6.079-3.715,9.271-5.309c30.581-15.027,69.581-10.027,95.852,12.209c2.563,2.254,4.987,4.651,7.244,7.178 c4.513,5.054,8.354,10.626,11.312,16.64C210.178,201.505,210.798,204.497,210.941,207.666z" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "rightEar", + "children": [ + { + "shape": { + "type": "path", + "path": "M64.857,195.606 c-6.59-7.181-15.047-10.664-19.467,3.676c-1.235,4.007-1.87,14.468,1.29,17.786c4.223,4.435,13.591,0.529,19.055-0.015" + }, + "fill": "#FFE8B0", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M52.407,196.744 c-1.702,3.613-1.257,7.505-1.27,11.424" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M51.772,209.438 c-3.39-4.661,0.922-5.769,5.078-6.347" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + }, + { + "name": "fgHair", + "shape": { + "type": "path", + "path": "M90.384,154.64c8.453-11.353,15.678-13.458,28.581-15.915c-1.382,3.376-3.89,7.352-5.179,11.16 c5.01-1.816,9.571-6.545,15.218-8.413c11.355-3.755,23.853-1.903,35.671-2.213c-3.004,3.712-4.912,7.88-2.025,11.447 c5.855-2.212,13.369-6.871,19.635-6.646c0.263,4.561-0.024,9.278,0.201,13.841c3.509-1.201,6.015-3.04,8.276-5.148 c2.263-2.108,3.761-4.049,4.942-5.2c1.063,2.408,2.134,5.334,2.24,8.494c-0.183,3.462-0.866,6.794-2.66,9.291 c3.663,0.65,6.098-2.021,8.35-4.479c-0.655,4.349-3.164,8.604-3.851,13.013c2.178-0.072,4.382,0.216,6.367-0.48 c-1.39,3.093-3.069,7.287-6.616,8.414c-4.476,1.423-4.354-0.992-7.315-4.332c-4.892-5.518-9.773-6.791-15.872-9.464 c-6.585-2.887-10.982-6.47-17.963-8.219c-8.994-2.255-19.864-3.867-28.093-5.196c2.466,1.967,1.138,5.594,0.659,8.625 c-2.729-0.646-4.41-3.813-6.301-5.158c0.953,3.195,0.983,6.953-2.134,8.491c-6.145-5.226-9.199-9.721-17.527-11.647 c1,1.83,1.728,4.208,1.396,6.402c-0.751,4.971-0.289,3.134-3.836,2.466c-5.192-0.977-9.953-3.677-15.815-4.496 c3.292,2.002,5.469,5.017,7.418,8.21c-2.651,0.404-6.238,0.257-8.382,1.671c2.456,0.38,3.44,2.166,3.197,4.714 c-7.45,0.386-13.623,0.731-19.915,5.434" + }, + "fill": "#FFF471", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + } + ] + }, + { + "name": "eyes", + "children": [ + { + "name": "eyes1", + "children": [ + { + "shape": { + "type": "path", + "path": "M123.163,176.668 c-5.066,1.17-9.01,7.888-13.666,10.335c-4.238,2.227-8.648,6.636-7.009,12.332c1.971,6.848,12.042,3.991,16.261,1.165 c5.282-3.539,9.59-8.517,12.006-14.524c1.523-3.787,2.568-7.272-1.509-9.391c-2.905-1.51-8.174-1.386-11.417-0.583" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M182.545,179.865 c-3.533,0.169-4.854-1.166-8.408-0.001c-3,0.983-6.239,1.936-8.852,3.743c-3.938,2.725-7.46,5.555-4.73,13.592 c1.974,5.811,8.791,7.571,14.656,6.667c5.537-0.854,9.078-4.977,11.408-10.007c3.666-7.918,0.942-11.639-6.742-13.659" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000", + "cap": "round" + } + }, + { + "shape": { + "type": "path", + "path": "M108.829,183.668c-1.308-1.03-4.557,0.011-5.6-1.733 c-1.056-1.765,1.735-5.409,2.984-6.192c5.684-3.562,15.946-0.39,19.95-6.742" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M163.877,167.198c2.369,1.282,6.539,0.307,9.408,0.815 c3.449,0.612,7.065,2.657,10.592,2.851" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M127.496,192.002c-4.917-2.12-9.188-1.708-8.608,4.942 c3.132,1.734,5.428-2.82,7.275-4.942" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M174.852,203.144c-0.293,0.12-0.307,0.577-0.942,0.282 c-1.605-3.188-0.404-6.507,2.676-8.192c2.15-1.176,5.67-1.759,7.471,0.359c0.199,0.234,0.412,0.521,0.515,0.813 c0.229,0.649-0.285,0.95-0.285,0.95s-3.988,6.009-3.285,1.934c0.438,1.743-5.537,5.743-2.287,1.653 c-1.955,2.583-2.524,1.977-3.859,2.868" + }, + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "eyes2", + "children": [ + { + "shape": { + "type": "path", + "path": "M98.668,186.108c0.668-8.915,15.545-13.749,22.667-15" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M169.667,178.108c5.307,3.436,16.928,5.632,19.668,12.333" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M105.334,197.775c8.085-4.283,17.059-2.8,25-6.333" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M164.001,198.775c4.656-0.417,9.664,1.805,14.334,2.017 c3.951,0.18,5.773,0.189,9,2.316" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M124.001,188.108c3.039-0.258,4.594,2.571,5.301,4.983 c-1.096,1.242-2.065,2.646-2.968,4.017" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M168.335,194.108c-1.77,2.293-4.869,3.271-6.299,5.91 c1.377,0.991,3.02,2.122,3.965,3.424" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + } + ] + }, + { + "name": "beard", + "children": [ + { + "shape": { + "type": "path", + "path": "M96.05,213.64 c-0.366,0.21-0.783,0.389-1.167,0.5" + }, + "fill": "#AFA8A5", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M102.55,211.973 c0.314-0.01,0.554-0.198,0.667-0.5" + }, + "fill": "#AFA8A5", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M105.717,208.806 c0.164-0.109,0.336-0.224,0.5-0.333" + }, + "fill": "#AFA8A5", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M111.05,207.973 c-0.651-1.81,0.859-2.262,2.333-1.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M117.717,209.806 c1.738,0,3.653,0.369,5.333,0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M132.717,214.473 c0.104-0.21,0.162-0.435,0.167-0.667" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M139.551,216.973 c0.215-0.175,0.465-0.426,0.666-0.667" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M144.551,213.306 c0.277-0.056,0.557-0.111,0.833-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M147.884,216.64 c0.195,0.045,0.369-0.013,0.5-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M148.384,214.14 c0.112-0.168,0.223-0.332,0.333-0.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M98.217,219.306c1.697-1.772,4.233-2.109,5.967-4.046c1.519-1.696,3.812-3.001,4.2-5.454" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M152.717,216.14 c0.611,0,1.224,0,1.834,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M160.384,217.473 c0.333,0,0.667,0,1,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M163.217,215.973 c0.321-0.042,0.658-0.175,0.834-0.333" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M164.217,218.806 c0.167,0,0.333,0,0.5,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M168.384,217.973 c0.057-0.056,0.111-0.111,0.167-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M169.884,225.806 c0.491-0.397,0.882-0.926,1.167-1.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M172.717,221.973 c0.057,0,0.111,0,0.167,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M171.717,229.806 c0.334,0.075,0.659,0.025,0.834-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M190.051,227.806 c0.163-0.242,0.398-0.423,0.666-0.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M197.384,221.473 c0.258-0.007,0.485-0.125,0.667-0.333" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M199.384,214.973 c-0.04-0.333,0.075-0.609,0.333-0.833" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M117.884,257.306 c0.056,0,0.111,0,0.167,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M142.717,252.473 c0.358,0.068,0.71,0.016,1-0.167" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M137.884,256.473 c0.277,0,0.557,0,0.833,0" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M160.884,252.973 c0.366-0.139,0.766-0.402,1-0.667" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M171.384,250.14 c0.235-0.264,0.476-0.562,0.667-0.834" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M89.384,243.973 c0.537,0.378,1.329,0.876,1.833,1.333" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M79.05,225.473 c0.087,0.272,0.143,0.55,0.167,0.833" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M73.884,222.64 c0,0.167,0,0.333,0,0.5" + }, + "fill": "none", + "stroke": { + "color": "#AAAAAA", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M72.55,219.806c0.466-0.325,0.875-0.797,1.167-1.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M71.717,211.973c0.422-0.553,0.776-1.305,1-2" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M78.55,214.473c0-0.111,0-0.222,0-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M79.384,218.806c-0.001-0.137,0.055-0.248,0.167-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M80.217,221.14c0.111,0,0.222,0,0.333,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M75.55,226.473c0.103-0.5,0.156-0.977,0.167-1.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M78.55,230.14c0.111,0,0.222,0,0.333,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M83.384,227.64c0.118-0.059,0.215-0.107,0.333-0.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M81.55,237.14c0.056,0,0.111,0,0.167,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M86.217,233.806c0.056,0,0.111,0,0.167,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M87.884,230.473c0.595-0.181,1.219-0.527,1.833-0.667" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M88.717,222.14 c-0.929,2.359-1.615,4.865-2.667,7.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M89.05,216.14 c0.784-0.736,1.709-1.565,2.833-1.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M94.217,210.14 c1.599-0.089,3.199-0.167,4.833-0.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M94.884,224.64 c0.052-0.588-0.004-1.155-0.167-1.667" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M92.384,228.306 c0.585-0.062,1.244-0.132,1.667-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M88.717,240.14 c0.111,0,0.222,0,0.333,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M95.884,243.306 c0.526,0.1,1.017-0.016,1.333-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M98.55,248.306 c0.069-0.24,0.265-0.926,0.333-1.166" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M96.55,249.806 c0.125,0.014,0.18-0.042,0.167-0.166" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M104.55,250.14 c0.01-0.238,0.126-0.428,0.333-0.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M106.884,251.973 c0.195,0.045,0.37-0.014,0.5-0.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M113.884,254.806 c0.758-0.586,1.595-1.171,2.382-1.774c0.072,0.376,0.418,0.686,0.48,1.079c0.833,0.265,1.624-0.021,1.638-0.971" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M122.217,254.64 c0.063-0.165,0.179-0.288,0.333-0.334" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M125.884,255.806 c1.13-0.745,2.783-0.962,3.667-2" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M132.217,255.973 c0.638-0.492,1.104-1.173,1.141-1.976c-1.11,0.063-1.449-0.888-1.475-1.857" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M129.717,249.306 c-0.045,0.153-0.168,0.271-0.333,0.334" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M136.551,252.306 c0.223,0,0.444,0,0.666,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M110.217,251.306 c0.056-0.057,0.111-0.11,0.167-0.166" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M140.717,251.806 c0.111,0,0.224,0,0.334,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M150.051,249.473 c0.111,0,0.223,0,0.333,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M143.217,255.473 c1.022-0.313,1.725-1.175,2.646-1.654c0.203,0.321,0.439,0.626,0.521,0.987" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M152.217,253.473 c0.165-0.063,0.288-0.179,0.334-0.333" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M155.051,254.64 c0.223,0,0.444,0,0.666,0" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M157.717,256.473 c0.326-0.027,0.546-0.073,0.834-0.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M163.217,252.64 c0.552-0.892,2.082-1.512,2.341-2.334c0.37-1.178-1.155-3.069-1.007-4.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M167.384,235.973 c0.118-0.54,0.354-1.064,0.667-1.5" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M170.717,242.806 c0-0.333,0-0.667,0-1" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M170.217,236.973 c0-0.333,0-0.667,0-1" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M179.051,235.806 c0.378-0.101,0.738-0.35,1-0.667" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M185.051,232.806 c0.379-0.319,0.656-0.702,0.833-1.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M188.051,231.14 c0.063-0.39,0.178-0.792,0.333-1.167" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M197.884,223.306 c-0.166,0.277-0.334,0.556-0.5,0.833" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + }, + { + "name": "mouths", + "children": [ + { + "name": "mouth1", + "children": [ + { + "shape": { + "type": "path", + "path": "M177.122,216.821c-0.515,2.282-5.213,3.21-7.434,3.854 c-3.254,0.945-6.596,1.345-9.895,1.851c-3.26,0.5-6.665,0.671-10.107,0.671c-3.596,0-6.645,0.559-10.106,0.671 c-3.105,0.1-6.898-0.474-9.694-1.3c-3.527-1.043-6.672-1.666-10.096-3.062c-2.823-1.152-5.746-1.876-8.462-3.143 c-2.594-1.209-6.084-1.994-8.221-3.552c-1.068,1.834-5.867,3.748-8.1,4.546c-2.444,0.874-8.881,2.725-7.817,5.512 c0.457,1.195,1.948,2.273,2.63,3.385c0.774,1.261,1.139,2.601,2.057,3.859c1.83,2.5,4.506,4.773,6,7.34 c1.308,2.249,2.096,4.74,4.01,6.669c2.214,2.233,5.792,2.635,9.231,2.399c7.028-0.479,13.982-2.129,20.481-3.983 c3.295-0.941,6.699-1.536,10.086-2.686c3.272-1.111,6.642-3,9.402-4.777c5.248-3.377,10.278-6.409,14.283-10.705 c1.479-1.587,3.429-2.503,5.149-3.859" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M135.25,241.319 c0.723-4.757-10.487-8.47-14.898-9.526c-3.09-0.74-6.68-1.17-9.858-1.712c-2.758-0.47-6.865-0.836-9.437,0.369 c-1.385,0.649-2.843,1.724-4.141,2.513c2.156,3.964,4.728,8.861,9.468,11.506c3.229,1.801,5.511,0.776,8.859,0.373 c3.045-0.369,6.046-0.703,9.029-1.721c3.479-1.186,7.228-2.385,10.978-2.475" + }, + "fill": "#FFC0C0", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M148.656,225.547c1.267,0.697,1.301,2.838,0.671,3.9 c-0.702,1.182-2.063,1.4-3.307,2.01c-2.271,1.116-4.58,2.624-7.481,2.638c-4.619,0.023-2.144-4.067-0.253-5.869 c2.405-2.292,5.057-2.72,8.72-2.512c0.588,0.034,1.095,0.041,1.65,0.168" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M130.299,223.365 c2.687,0.437,5.619,4.384,3.727,6.422c-1.234,1.33-7.94,1.391-9.915,1.296c-4.896-0.233-2.502-2.445-0.613-4.525 c1.604-1.767,5.088-3.249,7.833-3.36" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M113.178,217.157 c2.56,0.958,4.922,5.057,5.352,7.215c0.377,1.885-0.324,2.106-2.526,2.643c-1.366,0.333-3.636,0.723-5.105,0.385 c-2.506-0.577-5.883-5.051-4.909-7.223c1.03-2.298,5.944-2.923,8.427-2.852" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M99.359,217.662 c2.038,0.432,4.015,4.279,2.468,5.625c-1.083,0.943-5.221,1.795-6.799,1.589c-4.032-0.526-2.265-4.102-0.866-5.872 c0.706-0.894,1.049-1.976,2.514-2.186c1.627-0.233,2.501,0.99,3.921,1.346" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M181.815,222.896c-3.102-2.75-4.765-8.777-9.282-10.403" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "mouth2", + "children": [ + { + "shape": { + "type": "path", + "path": "M87.57,221.951c5.563-1.759,11.066-1.32,16.694-1.782c2.93-0.24,5.228-1.14,8.309-0.927c3.142,0.217,6.085-0.235,9.289,0.176 c7.136,0.914,13.96,0.598,21.112,1.506c3.654,0.464,7.219,0.609,10.811,0.869c4.017,0.291,7.646,1.582,11.433,2.623 c2.948,0.812,6.347,1.618,9.011,2.99c2.521,1.298,6.354,2.856,8.301,4.72c-2.775,0.027-5.602,2.603-8.021,3.769 c-2.93,1.412-5.741,2.949-8.656,4.432c-5.599,2.849-11.885,5.468-18.104,6.53c-6.793,1.161-13.195,2.107-20.067,2.197 c-7.699,0.102-14.313-4.705-20.735-8.396c-2.071-1.19-4.69-2.182-6.504-3.666c-1.792-1.466-3.469-3.386-5.154-4.984 c-2.703-2.564-7.519-5.649-8.13-9.438" + }, + "stroke": { + "color": "#000000", + "width": "3", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M87.785,228.193 c-5.907-3.235-0.344-9.531,3.971-11.424" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2" + } + }, + { + "shape": { + "type": "path", + "path": "M184.679,227.229c-1.534,2.583-2.548,5.334-4.024,7.889" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "width": "2", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M106.862,219.528 c-3.071-0.74-5.608,2.166-6.318,4.738c-0.379,1.375-0.494,2.55,0.748,3.337c1.519,0.962,2.905-0.052,4.418-0.332 c2.518-0.467,7.293,0.053,6.461-4.248c-0.568-2.938-3.743-3.682-6.338-3.335c-0.451,0.06-0.758,0.212-1.205,0.229" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M119.764,218.479 c-2.648,1.243-4.657,3.518-5.346,6.377c-0.866,3.594,3.9,3.711,6.356,2.865c2.64-0.91,4.77-3.351,3.299-6.133 c-1.01-1.91-3.979-2.548-6.026-2.823" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M130.388,219.492 c-1.753,1.382-4.069,4.525-4.835,6.61c-1.159,3.156,2.296,3.371,4.868,3.348c3.061-0.028,6.6-1.148,5.022-4.78 c-1.168-2.691-2.552-4.85-5.551-5.241" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M142.954,221.087 c-1.502,0.337-5.418,3.249-5.638,4.997c-0.292,2.311,4.855,4.536,6.854,4.234c2.503-0.377,4.384-3.175,3.167-5.65 c-0.92-1.873-3.36-2.252-4.508-3.932" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M155.354,222.664 c-2.038,0.426-4.212,2.287-4.766,4.444c-0.723,2.821,3.226,3.383,5.458,3.331c2.541-0.059,5.126-1.752,3.249-4.32 c-1.394-1.908-3.707-3.189-5.304-4.636" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M168.367,237.924 c-1.554-1.217-3.302-2.557-5.203-2.976c-2.973-0.654-3.537,2.131-3.377,4.406c0.205,2.913,1.032,3.883,3.901,2.344 c1.987-1.066,4.271-1.997,4.599-4.456" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M151.524,246.202 c-1.912-0.166-4.004-4.491-2.91-6.25c0.771-1.239,5.456-1.688,6.857-1.292c0.271,0.917,0.979,1.841,0.829,2.771 c-0.088,0.54-0.994,1.645-1.296,2.188c-1.08,1.951-2.133,1.866-3.998,2.685" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M145.911,241.458 c-0.209,1.649-0.215,2.702-1.528,3.801c-0.885,0.738-1.772,1.189-2.54,2.1c-0.786,0.933-1.226,2.38-2.792,1.813 c-1.042-0.377-1.959-2.318-2.138-3.312c-0.299-1.676-1.003-5.228,0.783-6.158c1.154-0.603,7.066-0.18,7.43,1.32" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M133.12,238.991 c-1.495-0.087-2.253-1.33-3.918-0.964c-1.42,0.311-2.489,1.354-2.54,2.836c-0.052,1.527,0.99,5.581,1.852,6.956 c2.363,3.771,4.329-1.535,5.516-3.159c1.117-1.525,2.643-2.053,2.271-3.958c-0.318-1.632-1.118-2.047-2.766-2.329 c-0.382-0.065-0.773-0.095-1.158-0.147" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M116.853,237.43 c-1.049,2.211-0.173,5.147,0.047,7.565c0.357,3.93,3.827,2.028,5.831,0.067c1.575-1.541,4.599-4.86,2.209-6.484 c-1.881-1.279-5.727-2.458-7.756-1.107" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M107.455,233.38 c-0.813,2.487-1.704,5.049,0.073,7.364c1.91,2.486,4.009,1.229,5.537-0.939c1.056-1.5,3.316-4.481,1.563-6.017 c-1.347-1.179-6.468-1.518-7.854-0.325" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "mouth3", + "children": [ + { + "shape": { + "type": "path", + "path": "M99.05,218.973c1.691-0.875,3.313-2.39,4.833-3.537c1.231-0.928,2.782-1.671,3.5-3.072c1.846,3.486,7.661,4.669,11.003,6.067 c3.553,1.486,7.174,3.066,10.784,4.166c4.271,1.301,9.277,1.67,13.721,2.343c4.155,0.629,9.979,1.365,14.162,0.496 c1.182-0.245,2.343-1.024,3.462-1.446c0.162,1.905-3.637,3.023-4.933,3.487c-2.435,0.871-4.18,2.541-6.362,3.871 c-1.623,0.989-2.974,1.669-4.755,2.117c-1.77,0.445-3.353,0.806-4.825,1.878c-5.915,4.311-15.264,3.247-22.424,3.13 c-5.384-0.088-6.719-5.372-9.337-9c-1.437-1.991-2.843-3.854-3.796-6.138c-0.871-2.086-1.119-4.582-2.033-6.528" + }, + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M107.217,227.973c1.182-2.033,4.375-2.176,6.5-1.963c2.879,0.289,4.124,1.217,6.168,3.167c1.834,1.749,5.906,5.509,5.64,8.271 c-2.808,0.89-7.847,0.402-10.346-1.104c-1.334-0.804-1.151-2.256-2.246-3.588c-0.712-0.866-1.836-2.673-2.855-3.311 c-0.209-0.94-2.106-1.499-3.028-1.805" + }, + "fill": "#F4BDBD", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + } + ] + } + ] + }, + { + "name": "personalProps", + "children": [ + { + "name": "hat", + "children": [ + { + "children": [ + { + "children": [ + { + "shape": { + "type": "path", + "path": "M88.374,173.145c0.474-0.074,16.606,2.725,18.01,5.879 c1.145,2.572,28.184,4.568,28.184,4.568l35.971-5.618l5.024,1.132l7.212,0.315l9.295,0.851l10.188,3.248l5.75,2.935 l1.615-1.832l-0.264-5.27l-3.968-7.087c0,0-22.045-13.031-23.272-13.703c-1.229-0.669-4.941-2.294-6.484-4.542 c-8.584-12.528-8.403-18.05-3.371-6.461c0,0,2.662-7.592,2.521-8.575c-0.144-0.982,0.354-5.031,0.354-5.031l2.396-6.832 c0,0-1.379-5.341-2.738-7.19c-1.356-1.844-15.793-4.078-18.162-4.011c-24.933,0.706-3.783,0.071-25.567,0.724 c-24.317,0.728-0.882-2.591-24.068,3.551c-24.228,6.418-5.35-1.298-23.187,6.142c-18.301,7.633-16.67,7.186-16.704,10.685 c-0.034,3.499-3.057-4.884-0.034,3.499c3.023,8.381,3.037-3.871,3.023,8.381c-0.015,12.252,6.696,4.557,1.678,12.373 c-5.017,7.813-3.831,7.91-0.179,8.543c17.017,2.953,4.157,4.378,17.427,3.175" + }, + "fill": "#FF0000", + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M156.604,114.92l-13.936,0.381l-11.633,0.343c-10.646,0.319-11.973-0.155-12.021-0.175l-0.599-0.238 l-0.577,0.514l0.049-0.047c-0.118,0.09-1.43,0.957-11.145,3.53c-9.989,2.646-12.812,2.931-13.421,2.704 c-0.822-0.306-0.821-0.306-7.791,2.604l-2.104,0.878c-16.037,6.689-17.342,7.324-17.342,10.316c0,0.019,0.001,0.041,0.001,0.06 c-0.224-0.108-0.459-0.199-0.787-0.04c-0.357,0.173-0.565,0.275-0.565,0.672c0,0.557,0.411,1.697,1.399,4.438 c0.924,2.561,1.71,3.671,2.714,3.833c0.083,0.014,0.164,0.02,0.241,0.02c0.007,0.584,0.01,1.339,0.01,2.313 c0,0.561-0.001,1.902-0.001,1.916c0,6.908,2.176,8.105,3.347,8.749c0,0,0.075,0.045,0.151,0.09 c-0.095,0.332-0.47,1.1-1.661,2.955c-2.509,3.908-3.516,5.931-3.516,7.303c0,0.358,0.068,0.671,0.196,0.962 c0.544,1.237,1.926,1.477,3.677,1.78l0.135,0.023c8.138,1.412,9.14,2.422,9.568,2.854c0.923,0.931,1.511,0.928,7.224,0.413 c0.06,0.014,0.102,0.068,0.165,0.071c2.167,0.105,16.131,3.138,17.087,5.288c1.147,2.578,16.416,4.228,29.023,5.159 l0.115,0.009c0,0,35.523-5.548,35.896-5.606c0.345,0.078,4.927,1.11,4.927,1.11l7.301,0.319c0,0,8.927,0.818,9.139,0.837 c0.202,0.064,9.854,3.142,10.006,3.19c0.143,0.073,6.368,3.251,6.368,3.251l2.397-2.719l-0.296-5.911l-4.213-7.526 l-0.231-0.137c-0.9-0.532-22.073-13.047-23.304-13.72c-0.001,0-0.734-0.38-0.734-0.38c-1.48-0.752-4.238-2.151-5.404-3.85 c-1.357-1.982-2.451-3.729-3.354-5.268c0.021-0.064,0.104-0.296,0.104-0.296c1.193-3.402,2.576-7.619,2.576-8.885 c0-0.063-0.004-0.118-0.011-0.165c-0.013-0.083-0.018-0.204-0.018-0.356c0-0.909,0.194-2.911,0.363-4.307 c0.072-0.205,2.46-7.013,2.46-7.013l-0.076-0.294c-0.146-0.566-1.468-5.584-2.9-7.532 C173.721,116.784,158.242,114.875,156.604,114.92z M131.097,117.644l11.614-0.342l13.951-0.382 c2.575-0.073,16.104,2.238,17.336,3.614c0.956,1.3,2.058,4.938,2.49,6.549c-0.188,0.536-2.33,6.642-2.33,6.642l-0.014,0.107 c-0.072,0.592-0.387,3.224-0.387,4.658c0,0.258,0.011,0.477,0.034,0.639c-0.006,0.493-0.768,3.026-1.659,5.709 c-2.14-4.566-2.792-4.606-3.242-4.629l-0.62-0.031l-0.354,0.571c-0.069,0.124-0.102,0.29-0.102,0.492 c0,2.273,4.134,9.172,6.992,13.346c1.456,2.12,4.51,3.669,6.149,4.501l0.682,0.353c1.139,0.622,20.813,12.25,23.012,13.549 c0.238,0.427,3.513,6.275,3.721,6.647c0.02,0.393,0.199,3.971,0.23,4.629c-0.229,0.262-0.472,0.535-0.832,0.944 c-1.069-0.546-5.132-2.619-5.132-2.619l-10.369-3.306l-9.403-0.86c0,0-6.995-0.307-7.169-0.315 c-0.168-0.038-5.124-1.155-5.124-1.155s-35.814,5.594-36.044,5.63c-12.419-0.922-25.993-2.687-27.285-4.058 c-1.366-3.097-13.245-5.574-17.517-6.211c-0.203-0.212-0.479-0.346-0.793-0.318c-3.083,0.28-5.996,0.544-6.4,0.369 c0-0.003-0.12-0.117-0.12-0.117c-0.703-0.708-1.879-1.895-10.646-3.416l-0.135-0.023c-0.827-0.143-2.075-0.359-2.188-0.614 c-0.021-0.048-0.033-0.111-0.033-0.193c0-0.592,0.632-2.179,3.205-6.187c1.488-2.318,2.024-3.388,2.024-4.188 c0-0.15-0.019-0.291-0.054-0.428c-0.181-0.712-0.758-1.03-1.179-1.261c-0.865-0.476-2.311-1.271-2.311-6.993 c0-0.014,0.001-1.098,0.001-1.56c0-4.969-0.065-4.992-0.833-5.258c-0.424-0.146-0.816,0.001-1.178,0.377 c-0.208-0.289-0.558-0.898-1.073-2.324c-0.205-0.568-0.385-1.068-0.542-1.506c0.587-0.423,0.632-1.277,0.636-1.644 l-0.014-0.825c-0.004-0.119-0.007-0.231-0.007-0.338c0-1.702,0.899-2.264,16.109-8.608l2.105-0.878 c4.165-1.739,5.948-2.482,6.375-2.562c0.817,0.296,2.292,0.597,14.579-2.658c8.169-2.164,10.697-3.187,11.58-3.704 C120.451,117.773,124.529,117.84,131.097,117.644z" + }, + "stroke": { + } + } + ] + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M155.146,147.93c4.88-9.398-5.344-20.199-12.649-21.176 c-12.05-1.61-13.404,10.426-13.684,21.258c3.73,2.016,8.915,3.425,11.721,6.534" + }, + "fill": "#FFFFFF", + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M133.446,127.979c-4.599,3.921-5.426,11.933-5.635,20.006l-0.017,0.654l4.415,2.067 c2.849,1.244,5.793,2.529,7.581,4.509c0.371,0.41,1.004,0.442,1.412,0.072c0.219-0.197,0.33-0.469,0.33-0.743 c0-0.239-0.084-0.479-0.258-0.67c-2.076-2.299-5.223-3.673-8.267-5.001c0,0-2.377-1.112-3.174-1.486 c0.223-7.385,1.021-14.572,4.909-17.887c1.892-1.614,4.386-2.189,7.621-1.757c4.143,0.554,9.086,4.472,11.5,9.113 c1.348,2.591,2.51,6.535,0.395,10.611c-0.254,0.49-0.063,1.093,0.426,1.348c0.49,0.254,1.095,0.063,1.351-0.427 c1.959-3.775,1.817-8.199-0.396-12.456c-2.731-5.251-8.203-9.53-13.012-10.172C138.853,125.257,135.763,126,133.446,127.979z" + }, + "stroke": { + } + } + ] + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M154.077,146.278c-2.156,1.18-4.24,2.619-6.256,4.01c-3.636,2.509-7.068,4.878-10.941,5.924 c-2.991,0.808-6.055,1.058-9.3,1.324c-3.222,0.263-6.553,0.536-9.783,1.406c-2.027,0.546-4.117,1.397-6.137,2.221 c-3.491,1.423-7.102,2.895-10.528,2.866c-0.552-0.005-1.004,0.439-1.009,0.991c-0.005,0.552,0.439,1.004,0.991,1.009 c3.828,0.033,7.627-1.516,11.301-3.014c2.054-0.837,3.994-1.628,5.902-2.142c3.054-0.823,6.292-1.088,9.425-1.344 c3.191-0.261,6.492-0.531,9.659-1.386c4.205-1.135,7.94-3.714,11.557-6.208c1.973-1.362,4.014-2.771,6.08-3.901 c0.484-0.265,0.662-0.873,0.396-1.357C155.168,146.193,154.562,146.014,154.077,146.278z" + }, + "stroke": { + } + } + ] + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M156.458,153.549c-2.619,0.064-5.709,0.812-8.98,1.604c-4.278,1.035-8.7,2.104-11.901,1.536 c-0.543-0.096-1.063,0.267-1.159,0.81c-0.097,0.544,0.267,1.063,0.81,1.16c3.613,0.641,8.24-0.481,12.72-1.562 c3.166-0.766,6.153-1.489,8.561-1.548c5.664-0.141,7.961,0.698,13.508,2.724c0.519,0.189,1.095-0.077,1.281-0.596 c0.189-0.519-0.076-1.091-0.596-1.282C165.069,154.337,162.501,153.399,156.458,153.549z" + }, + "stroke": { + } + } + ] + } + ] + } + ] + }, + { + "name": "textSurface", + "children": [ + { + "name": "spokenBubble", + "children": [ + { + "name": "textContainer", + "shape": { + "type": "path", + "path": "M225.719,45.307 c0-6.627,5.373-12,12-12h181.333c6.627,0,12,5.373,12,12v105.334c0,6.627-5.373,12-12,12H237.719c-6.627,0-12-5.373-12-12 V45.307z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "name": "textArrowBelow", + "shape": { + "type": "path", + "path": "M249.052,160.64 c-0.774,14.251-1.676,18.525-9.1,30.565c9.705-0.79,21.952-21.605,25.1-30.045" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "thoughtBubble", + "children": [ + { + "name": "textContainer_1_", + "shape": { + "type": "path", + "path": "M202.698,21.089 c19.686-26.45,59.686-24.45,79.747-0.084c2.696,1.349,5.57,1.709,7.472,0.781c15.28-13.888,33.271-14.043,49.893-7.839 c2.771,1.034,5.479,2.219,8.031,3.421C376.384-4.36,423.384,6.64,431.007,45.026c0,0-1.324,3.889,1.165,6.603 c18.212,11.011,26.212,32.011,22.212,53.011c-1,5.333-3.223,9.667-6.037,13.52c-2.813,3.854-1.381,0-2.612-0.591 c-1.351-0.929-3.351-0.929-4.351-1.929c16,7,27,22,30,39c2,21-8,41-27,50c-16,7.5-32.5,5.5-45.745-2.556 c-2.531-1.384-4.229-1.856-5.336-1.551c-1.919,0.107-3.919,2.107-5.919,2.107c4-1,6-5,10-6c-15,11-35,12-52,3c-13-7-20-20-24-34 c1,5,3,9,3.299,13.505c-0.396,0.708-3.423,2.219-6.654,3.466c-22.627,8.729-49.423,1.729-65.241-19.971 c-3.453,0-6.263,0.589-8.723,0.879c-17.301,3.2-32.382-7.709-40.771-22.689c-1.678-2.996-3.089-6.153-4.195-9.396 c-15.714-7.795-29.714-18.795-33.714-37.795c-5-25,11-45,29.842-57.667c0.72-2.335,1.697-4.636,3.007-6.896 C201.159,23.307,202.698,21.089,202.698,21.089z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M269.719,186.307c0,4.602-4.179,8.333-9.333,8.333s-9.334-3.731-9.334-8.333 c0-4.603,4.18-8.333,9.334-8.333S269.719,181.705,269.719,186.307z" + }, + "fill": "#FFFFFF", + "stroke": { + } + }, + { + "children": [ + { + "shape": { + "type": "path", + "path": "M269.719,186.307c0,4.602-4.179,8.333-9.333,8.333s-9.334-3.731-9.334-8.333 c0-4.603,4.18-8.333,9.334-8.333S269.719,181.705,269.719,186.307z" + }, + "fill": "none", + "stroke": { + } + }, + { + "shape": { + "type": "path", + "path": "M268.225,186.166c-0.563,8.736-13.981,9.286-15.633,0.853 c-1.785-9.125,15.018-10.254,15.649-0.451c0.125,1.929,3.078,1.388,2.955-0.521c-0.814-12.597-20.828-12.412-21.64,0.119 c-0.827,12.813,20.831,13.028,21.655,0.283C271.337,184.519,268.35,184.235,268.225,186.166z" + }, + "fill": "#FFFFFF", + "stroke": { + } + } + ] + } + ] + }, + { + "shape": { + "type": "path", + "path": "M260.386,188.307c0,3.498-2.984,6.333-6.667,6.333 c-3.682,0-6.667-2.835-6.667-6.333s2.985-6.333,6.667-6.333C257.401,181.974,260.386,184.809,260.386,188.307z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M238.386,196.974c0,1.289-1.045,2.333-2.334,2.333 c-1.288,0-2.333-1.045-2.333-2.333c0-1.288,1.045-2.333,2.333-2.333C237.341,194.64,238.386,195.685,238.386,196.974z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M285.719,179.974c0,4.602-4.253,8.333-9.5,8.333 s-9.5-3.731-9.5-8.333c0-4.603,4.253-8.333,9.5-8.333S285.719,175.372,285.719,179.974z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "yellBubble", + "children": [ + { + "shape": { + "type": "path", + "path": "M251.156,176.051l40.228-15.992" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "shape": { + "type": "path", + "path": "M280.932,149.385l-40.667,36.42" + }, + "fill": "none", + "stroke": { + "color": "#000000", + "cap": "round", + "join": "bevel" + } + }, + { + "name": "textContainer_2_", + "shape": { + "type": "path", + "path": "M217.778,34.644 c8.608,6.684,9.951,3.684,7.986-5.785c6.309,5.125,9.309,3.782,10.188-4.309c2.433,8.091,5.266,8.091,9.12-1.703 c6.063,9.793,13.146,9.793,24.043,3.878c6.103,5.915,16.02,5.915,20.094-4.64c17.178,10.555,28.511,10.555,45.233-5.505 c5.94,16.06,17.272,16.06,18.835,1.458c19.688,14.603,29.604,14.603,46.749-17.802c-0.145,32.405,6.938,32.405,29.26,16.182 c-12.403,16.223-9.57,16.223,4.813,6.576c-11.069,9.646-8.069,10.99,4.333,9.089c-8.061,6.244-6.717,9.244,2.533,11.068 c-9.25,1.489-9.25,5.703-0.314,13.07c-8.936,6.115-8.936,15.385,7.513,10.932c-16.447,24.677-16.447,35.631,14.938,36.553 c-31.385,19.303-31.385,28.571-4.39,40.526c-26.995,1.528-26.995,5.741-5.942,17.857c-21.053-8.801-22.396-5.802-9.525,11.916 c-17.213-13.374-20.213-12.03-12.048,8.029c-11.479-20.06-14.313-20.06-10.554,3.532c-13.676-23.591-20.759-23.591-29.813-2.664 c-7.944-20.927-17.861-20.927-27.072,12.467c-12.039-33.395-23.373-33.395-23.147-1.581 c-22.891-31.814-34.225-31.814-61.518-8.479c6.042-23.335-3.874-23.335-11.899-9.703c-8.976-13.632-16.059-13.632-23.927,4.361 c-2.049-17.993-4.882-17.993-10.51-1.486c2.314-16.508-0.686-17.851-12.385-5.019c7.355-17.175,6.013-20.176-10.271-7.879 c16.283-15.61,16.283-19.824-9.255-12.972c25.538-20.334,25.538-29.603,1.919-46.578c23.619-3.249,23.619-14.204-0.313-25.522 c23.933-8.905,23.933-18.175,7.798-37.429C226.385,48.854,226.385,44.641,217.778,34.644z" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + } + ] + } + ] + } +] \ No newline at end of file diff --git a/includes/js/dojox/gfx/demos/data/LarsDreaming.svg b/includes/js/dojox/gfx/demos/data/LarsDreaming.svg new file mode 100644 index 0000000..3f4b903 --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/LarsDreaming.svg @@ -0,0 +1,536 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/includes/js/dojox/gfx/demos/data/Nils.json b/includes/js/dojox/gfx/demos/data/Nils.json new file mode 100644 index 0000000..59e40cb --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/Nils.json @@ -0,0 +1,717 @@ +[ + { + "name": "nils_1_", + "children": [ + { + "name": "lowerBody", + "children": [ + { + "name": "leftShoe", + "children": [ + { + "shape": { + "type": "path", + "path": "M44.787,442.042c13.536-0.097,28.515-2.647,40.667-8.815 c13.064-6.631,3.188-24.604,0.553-34.404c-5.771-1.73-10.549-4.837-16.568-0.148c-4.371,3.405-6.025,11.462-2.07,15.501 c-3.212,7.339-17.804,1.912-23.732,6.7c-5.825,4.706-7.32,17.966,0.484,21.167" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M133.453,425.375c0.901-2.979,2.793-5.781,4.667-8" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M56.787,426.708c-2.551-2.07-3.97-5.252-5.333-8" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "rightShoe", + "children": [ + { + "shape": { + "type": "path", + "path": "M111.453,402.042c-2.005-0.426-3.947-0.363-5.899-0.566 c-0.104,2.376,0.438,5.478,0.048,7.751c-0.4,2.327-1.597,4.06-2.146,6.817c-0.975,4.9,0.412,10.561,3.813,13.517 c3.718,3.23,8.442,2.56,12.87,3.797c4.256,1.189,7.959,3.502,12.5,4.849c9.169,2.717,20.433,7.657,25.649-4.685 c2.797-6.618-0.894-5.624-6.331-7.982c-4.049-1.757-6.774-4.353-10.32-7.014c-4.123-3.095-8.203-5.957-13.415-6.584 c-0.11-3.353,1.616-5.692,1.132-9.117c-5.299-2.318-13.883-3.984-19.233-0.116" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M62.787,424.708c-1.417-2.271-3.012-5.388-2.667-8.666" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M141.453,428.042c2.076-1.991,4.274-3.745,6-6" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "leftLeft", + "shape": { + "type": "path", + "path": "M111.687,360.891c0.036,4.747,1.844,9.223,1.56,14.078 c-0.24,4.099-1.372,8.075-1.553,12.199c-0.2,4.558-1.141,9.069-1.142,13.648c0,3.48-0.275,5.533,3.084,7.379 c2.301,1.264,4.909,1.163,7.094-0.113c2.993-1.748,2.841-3.747,2.868-6.904c0.025-2.952,0.712-5.943,1.162-8.841 c0.446-2.868,0.401-5.667,0.398-8.578c-0.004-3.788,0.138-7.556,0.003-11.357c-0.118-3.318-1.49-6.782-1.279-10.093" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "name": "rightLeg", + "shape": { + "type": "path", + "path": "M74.107,353.8c-0.57,1.485-0.055,3.729-0.142,5.357 c-0.076,1.44-0.315,2.774-0.571,4.184c-0.786,4.316-1,8.786-1.732,13.181c-1.158,6.942-0.906,14.193-1.777,21.167 c-0.456,3.648,0.862,8.169,5.499,7.139c2.579-0.572,4.859-3.016,5.846-5.361c2.937-6.981-0.974-13.832-0.457-21.057 c0.331-4.619,2.141-8.637,3.402-13.056c0.769-2.694,1.709-5.131,1.703-7.972c-0.004-1.809,0-3.616,0-5.425" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "name": "pants", + "children": [ + { + "name": "pants_1_", + "shape": { + "type": "path", + "path": "M72.453,299.375 c1.947,19.47-1.848,38.143-0.849,57.849c3.905,0.681,11.166,0.417,14.849-0.849c7.135-2.453,6.497-2.631,7-11 c0.81-13.479-2.849-20.278,12.845-17.853c-1.125,13.305-9.43,25.115-3.42,38.649c8.404-0.38,20.265,0.661,28.427-1.944 c0.505-10.198-1.523-17.622-2.853-26.853c-1.398-9.708,3.313-18.866-1.174-27.826c-9.218,0.693-18.358,2.747-27.722,0.798 c-9.863-2.054-18.89-8.623-29.104-8.972" + }, + "fill": "#ADA274", + "stroke": { + "color": "#000000" + } + } + ] + } + ] + }, + { + "name": "leftArm_1_", + "children": [ + { + "name": "leftArm", + "shape": { + "type": "path", + "path": "M161.453,199.375c-6.73,0.606-12.711,7.192-9.248,13.248 c3.358,5.87,13.618,5.538,19.021,6.979c4,1.066,16.837,3.192,19.52,5.703c3.974,3.72,5.243,15.844,5.854,20.924 c13.641,4.354,26.949-0.671,33.102-13.826c5.331-11.398-5.783-19.505-17.098-22.174c1.771-8.465,14.167-32.061-0.128-36.899 c-4.761-1.611-15.726,3.346-17.801,7.272c-3.095,5.855-0.055,15.902-0.374,22.623c-13.399,0.68-27.351-3.555-39.849-1.849" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M221.453,220.375c-4.604-1.889-17.369-6.456-21.801-1.801 c-4.797,5.039,1.256,14.077,6.027,16.578c4.118,2.159,20.628,4.348,24.575,1c4.999-4.241,2.906-14.993-2.801-17.777" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M214.453,253.375c-1.006,3.482-0.767,9-3.174,12.826 c-15.878,0.834-16.244-5.43-25.674-14.571c10.53-5.253,19.583,4.754,29.849,2.745" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M226.453,239.375c0.54,16.962-8.377,15.391-21.023,12.023 c-17.34-4.617-11.577-7.176,3.023-13.023" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M208.453,188.375c-4.474,0.83-8.972-0.434-11-4" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M203.453,221.375c6.112-0.45,18.967,6.649,8,10" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M195.453,258.375c3.441-0.666,5.408-2.2,4-5" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "rightArm", + "children": [ + { + "shape": { + "type": "path", + "path": "M39.453,187.375c-3.104,7.216-3.137,14.998-7.278,21.997 c-5.137,8.684-9.794,6.9-17.5,12.281c-8.803,6.146-12.141,29.697-14.095,40.548c20.2,3.536,18.779-23.776,21.649-34.524 c0.975,13.012-0.289,26.468,0.374,39.546c2.257,0.582,6.44,0.582,8.697,0c2.04-10.494-3.53-22.034-0.852-33.546 c0.009,7.58-2.598,32.2,10.852,28.546c0.514-10.124-1.899-18.938-4.868-25.972c2.181,8.766,4.798,18.48,15.845,15.949 c6.407-12.781-3.909-15.105-8.048-25.604c-2.531-6.422,0.527-25.44,6.223-31.223" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M6.453,248.042c2.111,0,6.324-0.997,6.667,1.666" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M22.453,255.375c2.85-0.37,4.155,0.539,4.999,3.001 c1.085,3.168-0.233,4.173-2.999,5.332" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M31.787,255.042c3.675-0.503,7.077,4.971,3,6" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M48.453,235.708c-5.387-0.935-3.676,10.551,3.667,8.667" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M207.453,241.375c2.63,1.686,2.368,4.909,1.884,7.884 c-0.744,0.175-1.23,0.456-1.884,0.783" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "shirt", + "children": [ + { + "name": "mainShirt", + "shape": { + "type": "path", + "path": "M39.453,189.375 c0.777-3.467,1.211-7.217,1.151-10.849c14.871-1.403,32.372-7.656,46.875-11.125c9.423-2.254,31.959-20.14,39.244-11.079 c3.778,4.7,2.066,16.102,5.456,22.08c2.827,4.986,9.093,12.445,13.003,16.217c5.193,5.009,15.695-3.271,18.271,2.754 c3.024,7.075-0.511,20.739-10.02,18.016c-5.084-1.456-12.238-5.093-15.228-9.769c-4.055-6.341-8.831-13.012-10.53-19.167 c-0.713,10.697,1.173,22.369,2.726,32.92c1.637,11.128,1.886,22.261,3.052,34c2.02,20.336,6.915,42.053,10.845,61.855 c-14.599,4.091-47.868-3.832-47.868-3.832s-14.457-3.595-21.2-5.801c-8.131-2.661-21.777-11.223-13.777-11.223 s-3.063-9.756,2.468-40.878s14.003-39.61,19.806-56.122c1.387-3.946,2.399-8.004,4.375-11.845 c-17.565,1.273-26.117,7.964-40.475,16.742c-2.413-9.11-9.707-14.336-17.174-18.897" + }, + "fill": "#4867FF", + "stroke": { + "color": "#000000", + "width": "2" + } + }, + { + "name": "highlight", + "shape": { + "type": "path", + "path": "M99.453,179.375 c-5.364,2.937-10.603,8.065-17,8" + }, + "fill": "#4867FF", + "stroke": { + "color": "#000000", + "width": "2" + } + }, + { + "name": "logo", + "children": [ + ] + } + ] + }, + { + "name": "heads", + "children": [ + { + "name": "head1", + "children": [ + { + "name": "hair_1_", + "shape": { + "type": "path", + "path": "M60.453,97.375c-3.965-0.012-7.98,0.045-11.897-0.147 c2.645-5.735,10.791-8.417,14.794-13.65c-2.384,0.19-5.083-0.61-7.543-0.154c2.395-1.359,4.008-3.487,6.347-4.846 c-2.993-0.207-6.326-0.467-9.399-0.18c2.893-0.874,5.243-2.063,7.821-3.05c-0.92-0.166-4.625-2.732-6.772-4.221 c5.187-4.255,12.317-5.834,17.573-8.534c-2.844-0.13-5.037-1.713-7.75-2.393c-0.424-7.244-1.302-14.461-1.223-21.475 c2.166,2.761,3.541,5.976,4.849,8.546c-0.996-11.489,4.773-13.594,13.025-18.797c0.403,1.91,1.943,3.845,2.229,5.546 c1.27-13.312,22.924-28.644,34.016-33.272c0.039,6.247-2.955,11.957-5.365,17.475c-0.365,0.375-0.375,0.366-0.028-0.028 c5.849-6.92,14-8.882,22.143-10.721c-1.215,5.635-5.28,10.684-6.698,16.602c6.258-10.069,20.421-4.135,27.949-11.351 c-1.011,3.251-2.028,6.254-3.143,9.276c7.035-8.774,15.902-11.37,25.894-14.499c-0.668,7.995-10.243,18.061-0.822,20.872 c8.889,2.653,17.435-7.31,26.698-6.075c-2.976,1.954-5.822,4.12-8.614,6.345c7.596,2.01,18.243,0.852,26.614,0.658 c-4.125,3.304-9.116,7.352-9.593,12.943c3.896-0.826,8.6-1.318,12.741-0.725c-1.013,1.726-1.479,5.845-2.718,7.678 c3.136-0.265,6.17,1.053,8.519,1.452c-3.019,0.804-5.247,3.16-7.566,4.52c3.765,0.755,7.282,2.001,10.844,3.398 c-3.322,1.78-5.724,5.475-4.776,9.657c0.798,0.374,2.536,0.977,2.995,1.147c-6.481,3.645-21.331-1.522-28.945-2.752 c-13.967-2.257-27.844-4.641-41.913-6.244c-17.039-1.941-37.716-3.446-54.359,1.025C83.983,67.42,68.871,76.651,58.453,98.375" + }, + "fill": "#605542", + "stroke": { + "color": "#000000" + } + }, + { + "name": "neck", + "shape": { + "type": "path", + "path": "M108.453,132.375c0.902,8.412-0.835,20.235-3.849,27.797 c4.164,2.769,15.721,4.339,19.868,0c3.538-3.701,1.964-17.522,1.98-22.797" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "name": "leftEar_1_", + "children": [ + { + "name": "leftEar", + "shape": { + "type": "path", + "path": "M232.453,76.375c10.186-6.915,21.465,6.994,19.052,17 c-2.781,11.53-20.253,15.518-27.052,5" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M245.453,91.375c-0.398-2.267-1.99-4.77-3.171-6.829 c-2.738-0.936-5.713-1.545-8.829-1.171" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M238.453,90.375c1.863-0.367,3.589-1.433,5-3" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "headShape", + "shape": { + "type": "path", + "path": "M116.453,35.375 c-13.417,2.219-31.83,24.639-39.777,35.055c-8.128,10.652-24.737,25.747-20.219,39.945 c5.161,16.221,22.089,14.526,34.025,19.972c15.448,7.047,30.645,11.875,46.749,14.251c18.146,2.676,27.633,0.161,44.223-7.972 c15.701-7.697,29.862-9.589,41.801-24.303c8.182-10.084,15.033-28.733,8.174-38.923c-6.159-9.151-21.79-19.289-31.201-25.75 c-12.144-8.339-26.876-10.032-41-11.274c-15.007-1.32-33.207-3.056-47.774,1" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "name": "rightEar_1_", + "children": [ + { + "name": "rightEar", + "shape": { + "type": "path", + "path": "M66.453,94.375 c-10.188-4.124-23.701-5.729-27.774,7.226c-4.779,15.198,14.506,23.077,25.774,15.774" + }, + "fill": "#FFF0A9", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M42.453,106.375c4.149-4.954,11.06-7.737,16-10" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M48.453,100.375c1.337,3.541,2.787,6.955,5,10" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "adamsApple", + "shape": { + "type": "path", + "path": "M113.453,152.375c-0.526-2.327,1.546-3.837,5-4" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + } + ] + }, + { + "name": "expressions", + "children": [ + { + "name": "confused", + "children": [ + { + "name": "mouth_1_", + "children": [ + { + "name": "mouth", + "shape": { + "type": "path", + "path": "M102.148,120.014c13.398-6.9,33.568-7.688,49-10.026 c12.555-1.903,36.519-2.575,44,9.026" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "name": "tooth_1_", + "shape": { + "type": "path", + "path": "M178.148,109.014 c-0.563-2.655-0.017-6.196,0.151-8.849c4.788-0.944,9.637,0.768,13.675,3.022c0.664,3.187,0.065,6.267-1.826,8.826" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "name": "tooth", + "shape": { + "type": "path", + "path": "M168.148,108.014c-2.021-7.958,5.04-7.752,10.826-6.826 c1.286,2.446,1.752,5.863,1.022,8.675c-3.801,0.292-8.049,0.308-10.849-0.849" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "eyes", + "children": [ + { + "name": "rightEye", + "shape": { + "type": "path", + "path": "M121.148,52.014 c-6.562,8.145-20.057,16.28-21.023,26.977c-1.104,12.227,10.759,15.164,21.02,11.798c18.8-6.168,24.482-40.499,0.004-39.774" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "name": "pupilRight", + "shape": { + "type": "path", + "path": "M112.148,61.014c-7.625,3.067-4.047,12.428,3.826,10.826 C118.354,67.432,118.046,61.261,112.148,61.014" + }, + "stroke": { + "color": "#000000" + } + }, + { + "name": "leftEye", + "shape": { + "type": "path", + "path": "M184.148,55.014c-13.391-8.758-17.664,28.504,5,25.996 c10.862-1.201,14.124-12.581,8.004-19.996c-6.121-7.415-14.988-4.947-22.004-8" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "name": "pupilLeft", + "shape": { + "type": "path", + "path": "M176.148,54.014c-2.04,2.896-2.657,6.347-1.849,9.849 C184.707,66.621,182.108,56.322,176.148,54.014" + }, + "stroke": { + "color": "#000000" + } + } + ] + } + ] + }, + { + "name": "confused2", + "children": [ + { + "name": "rightEye_1_", + "shape": { + "type": "path", + "path": "M121.148,52.014 c-6.562,8.145-20.057,16.28-21.023,26.977c-1.104,12.227,10.759,15.164,21.02,11.798c18.8-6.168,24.482-40.499,0.004-39.774" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "name": "pupilRight_1_", + "shape": { + "type": "path", + "path": "M112.148,61.014 c-7.625,3.067-4.047,12.428,3.826,10.826C118.354,67.432,118.046,61.261,112.148,61.014" + }, + "stroke": { + "color": "#000000" + } + }, + { + "name": "leftEye_1_", + "shape": { + "type": "path", + "path": "M184.148,55.014 c-13.391-8.758-17.664,28.504,5,25.996c10.862-1.201,14.124-12.581,8.004-19.996c-6.121-7.415-14.988-4.947-22.004-8" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "name": "pupilLeft_1_", + "shape": { + "type": "path", + "path": "M176.148,54.014 c-2.04,2.896-2.657,6.347-1.849,9.849C184.707,66.621,182.108,56.322,176.148,54.014" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M114.934,118.74 c18.933-4.896,31.704-2.456,49.826,1.171c6.734,1.348,17.654,7.566,23.408,0.323c5.436-6.841-0.011-16.179-7.237-17.994" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "talking", + "children": [ + { + "shape": { + "type": "path", + "path": "M150.536,116.479c0.413,18.115,48.746,18.222,37.276-7.278 c-10.396-1.757-28.836,2.451-38.776,5.778" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M103.453,104.875c-2.277,2.169-1.729,7.324-4.849,8 c8.889,3.074,18.975,7.877,28.849,6.998c6.759-0.602,18.439-1.511,23.5-5.998" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M104.453,64.875 c-6.218-0.224-17.093,9.247-13.875,15.887c2.822,5.825,15.087,4.174,20.375,3.113c4.505-0.904,7.783-1.37,9.889-6.123 c1.107-2.499,2.855-9.088,1.623-11.889c-2.859-6.496-15.374-3.248-19.512,0.012" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M176.953,59.875 c-4.742,8.403,0.46,13.596,6.486,18.376c4.779,3.791,15.903,8.529,19.512,0.622c8.012-17.554-22.026-19.554-32.498-17.887 c-0.345,0.055-1.151,0.291-1.5,0.389" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M98.953,66.875c-6.969-2.545-10.165,5.418-3.002,8.05 c2.178-2.129,5.596-6.88,2.502-9.05" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M178.453,60.875c-5.534,0.708-5.259,9.173,0.5,7.387 c6.145-1.906,5.217-9.047-1.5-8.387" + }, + "stroke": { + "color": "#000000" + } + } + ] + }, + { + "name": "talking2", + "children": [ + { + "shape": { + "type": "path", + "path": "M102.87,94.503c-2.279,15.037-5.934,27.828,15.027,23.027 c15.334-3.512,25.379-13.239,28.973-28.027" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M92.87,104.503 c4.248-16.004,34.717-10.765,47.052-11.948c8.414-0.807,15.879-1.97,24.948-1.055c8.295,0.837,19.3,2.941,27-0.997" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M84.87,73.503c2.341-8.752,12.467-12.772,19-18" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M181.87,59.503c8.968-3.27,16.681,2.245,25,3" + }, + "fill": "none", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M98.87,68.503 c-7.218,11.165,3.031,17.234,13.003,17.997c13.201,1.009,21.125-8.677,18.845-21.842c-11.637-0.604-21.219,1.818-31.849,2.845" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M178.87,67.503 c-9.045,2.007-6.264,11.616-1.249,15.249c3.778,2.737,13.479,4.477,18.249,2.528C210.946,79.123,185.327,71.038,178.87,67.503" + }, + "fill": "#FFFFFF", + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M115.87,85.503c2.365-1.63,3.646-3.553,2.826-6.826 c-16.491-8.159-17.436,11.182-1.826,8.826" + }, + "stroke": { + "color": "#000000" + } + }, + { + "shape": { + "type": "path", + "path": "M174.87,80.503c-0.492-1.165-0.677-2.687-0.872-3.826 c3.483-0.285,7.207-0.292,10.698-0.023c3.568,7.301-6.079,7.593-10.826,5.849" + }, + "stroke": { + "color": "#000000" + } + } + ] + } + ] + } + ] + } +] \ No newline at end of file diff --git a/includes/js/dojox/gfx/demos/data/Nils.svg b/includes/js/dojox/gfx/demos/data/Nils.svg new file mode 100644 index 0000000..48908a2 --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/Nils.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/includes/js/dojox/gfx/demos/data/buratino-bg.png b/includes/js/dojox/gfx/demos/data/buratino-bg.png new file mode 100644 index 0000000..ee50a15 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-bg.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-head.png b/includes/js/dojox/gfx/demos/data/buratino-head.png new file mode 100644 index 0000000..d576873 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-head.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-left-arm.png b/includes/js/dojox/gfx/demos/data/buratino-left-arm.png new file mode 100644 index 0000000..1e620f3 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-left-arm.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-left-leg.png b/includes/js/dojox/gfx/demos/data/buratino-left-leg.png new file mode 100644 index 0000000..1ae5600 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-left-leg.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-lollipop.png b/includes/js/dojox/gfx/demos/data/buratino-lollipop.png new file mode 100644 index 0000000..9a52c1e Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-lollipop.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-nose-large.png b/includes/js/dojox/gfx/demos/data/buratino-nose-large.png new file mode 100644 index 0000000..a0e38fd Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-nose-large.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-nose-medium.png b/includes/js/dojox/gfx/demos/data/buratino-nose-medium.png new file mode 100644 index 0000000..f38e205 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-nose-medium.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-right-arm.png b/includes/js/dojox/gfx/demos/data/buratino-right-arm.png new file mode 100644 index 0000000..206bdb1 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-right-arm.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-right-leg.png b/includes/js/dojox/gfx/demos/data/buratino-right-leg.png new file mode 100644 index 0000000..cd0e172 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-right-leg.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino-torso.png b/includes/js/dojox/gfx/demos/data/buratino-torso.png new file mode 100644 index 0000000..64c2336 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino-torso.png differ diff --git a/includes/js/dojox/gfx/demos/data/buratino.jpg b/includes/js/dojox/gfx/demos/data/buratino.jpg new file mode 100644 index 0000000..95aaf05 Binary files /dev/null and b/includes/js/dojox/gfx/demos/data/buratino.jpg differ diff --git a/includes/js/dojox/gfx/demos/data/buratino.json b/includes/js/dojox/gfx/demos/data/buratino.json new file mode 100644 index 0000000..45ed668 --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/buratino.json @@ -0,0 +1,12 @@ +[ + {name: "bg", shape: {type: "image", width: 321, height: 355, src: "data/buratino-bg.png"}}, + {name: "left-arm", shape: {type: "image", width: 111, height: 40, src: "data/buratino-left-arm.png"}}, + {name: "right-arm", shape: {type: "image", width: 59, height: 130, src: "data/buratino-right-arm.png"}}, + {name: "left-leg", shape: {type: "image", width: 152, height: 99, src: "data/buratino-left-leg.png"}}, + {name: "right-leg", shape: {type: "image", width: 104, height: 158, src: "data/buratino-right-leg.png"}}, + {name: "torso", shape: {type: "image", width: 90, height: 130, src: "data/buratino-torso.png"}}, + {name: "head", shape: {type: "image", width: 116, height: 139, src: "data/buratino-head.png"}}, + {name: "nose-medium", shape: {type: "image", width: 50, height: 43, src: "data/buratino-nose-medium.png"}}, + {name: "nose-large", shape: {type: "image", width: 70, height: 66, src: "data/buratino-nose-large.png"}}, + {name: "lollipop", shape: {type: "image", width: 82, height: 144, src: "data/buratino-lollipop.png"}} +] diff --git a/includes/js/dojox/gfx/demos/data/svg2gfx.xsl b/includes/js/dojox/gfx/demos/data/svg2gfx.xsl new file mode 100644 index 0000000..90a463f --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/svg2gfx.xsl @@ -0,0 +1,72 @@ + + + + + + + + fill: " + + ", + + + + + stroke: { + + color: " + + ", + + + width: " + + ", + + + cap: " + + ", + + + join: " + + ", + + }, + + + { + + name: " + + ", + + children: [ + + ]}, + + + { + + name: " + + ", + + shape: {type: "path", path: " + + "}, + + + + + + + }, + + + [ + + ] + + diff --git a/includes/js/dojox/gfx/demos/data/transform.json b/includes/js/dojox/gfx/demos/data/transform.json new file mode 100644 index 0000000..60bd466 --- /dev/null +++ b/includes/js/dojox/gfx/demos/data/transform.json @@ -0,0 +1,1567 @@ +[ + { + "children": [ + { + "shape": { + "type": "line", + "x1": 0, + "y1": 0, + "x2": 500, + "y2": 0 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 0, + "x2": 0, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 50, + "x2": 500, + "y2": 50 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 50, + "y1": 0, + "x2": 50, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 100, + "x2": 500, + "y2": 100 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 100, + "y1": 0, + "x2": 100, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 150, + "x2": 500, + "y2": 150 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 150, + "y1": 0, + "x2": 150, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 200, + "x2": 500, + "y2": 200 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 200, + "y1": 0, + "x2": 200, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 250, + "x2": 500, + "y2": 250 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 250, + "y1": 0, + "x2": 250, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 300, + "x2": 500, + "y2": 300 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 300, + "y1": 0, + "x2": 300, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 350, + "x2": 500, + "y2": 350 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 350, + "y1": 0, + "x2": 350, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 400, + "x2": 500, + "y2": 400 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 400, + "y1": 0, + "x2": 400, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 450, + "x2": 500, + "y2": 450 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 450, + "y1": 0, + "x2": 450, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 0, + "y1": 500, + "x2": 500, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + }, + { + "shape": { + "type": "line", + "x1": 500, + "y1": 0, + "x2": 500, + "y2": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + } + } + ], + "name": "grid" + }, + { + "children": [ + { + "shape": { + "type": "rect", + "x": 0, + "y": 0, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 0, + "y": 100, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 0, + "y": 200, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 0, + "y": 300, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 0, + "y": 400, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 50, + "y": 50, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 50, + "y": 150, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 50, + "y": 250, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 50, + "y": 350, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 50, + "y": 450, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 100, + "y": 0, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 100, + "y": 100, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 100, + "y": 200, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 100, + "y": 300, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 100, + "y": 400, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 150, + "y": 50, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 150, + "y": 150, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 150, + "y": 250, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 150, + "y": 350, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 150, + "y": 450, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 200, + "y": 0, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 200, + "y": 100, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 200, + "y": 200, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 200, + "y": 300, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 200, + "y": 400, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 250, + "y": 50, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 250, + "y": 150, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 250, + "y": 250, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 250, + "y": 350, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 250, + "y": 450, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 300, + "y": 0, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 300, + "y": 100, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 300, + "y": 200, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 300, + "y": 300, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 300, + "y": 400, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 350, + "y": 50, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 350, + "y": 150, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 350, + "y": 250, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 350, + "y": 350, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 350, + "y": 450, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 400, + "y": 0, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 400, + "y": 100, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 400, + "y": 200, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 400, + "y": 300, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 400, + "y": 400, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 450, + "y": 50, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 450, + "y": 150, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 450, + "y": 250, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 450, + "y": 350, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + }, + { + "shape": { + "type": "rect", + "x": 450, + "y": 450, + "width": 50, + "height": 50, + "r": 0 + }, + "fill": { + "g": 0, + "b": 0, + "a": 0.1, + "r": 255 + } + } + ], + "name": "checkerboard" + }, + { + "shape": { + "type": "rect", + "x": 0, + "y": 0, + "width": 100, + "height": 100, + "r": 0 + }, + "transform": { + "dx": 100, + "dy": 100, + "xx": 1, + "xy": 0, + "yx": 0, + "yy": 1 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + }, + "fill": { + "type": "linear", + "x1": 0, + "y1": 0, + "x2": 100, + "y2": 100, + "colors": [ + { + "offset": 0, + "color": { + "r": 0, + "g": 128, + "b": 0, + "a": 1 + } + }, + { + "offset": 0.5, + "color": { + "g": 0, + "b": 0, + "r": 255, + "a": 1 + } + }, + { + "offset": 1, + "color": { + "r": 0, + "g": 0, + "b": 255, + "a": 1 + } + } + ] + }, + "name": "rect with color gradient" + }, + { + "shape": { + "type": "rect", + "x": 0, + "y": 0, + "width": 100, + "height": 100, + "r": 0 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + }, + "fill": { + "type": "linear", + "x1": 0, + "y1": 0, + "x2": 100, + "y2": 100, + "colors": [ + { + "offset": 0, + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + } + }, + { + "offset": 1, + "color": { + "r": 255, + "g": 255, + "b": 255, + "a": 1 + } + } + ] + }, + "name": "rect with gray gradient" + }, + { + "children": [ + { + "shape": { + "type": "rect", + "x": 200, + "y": 200, + "width": 100, + "height": 100, + "r": 0 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + }, + "fill": { + "r": 0, + "g": 128, + "b": 0, + "a": 1 + }, + name: "green rect" + }, + { + "shape": { + "type": "rect", + "x": 0, + "y": 0, + "width": 100, + "height": 100, + "r": 0 + }, + "transform": { + "xx": 0.8660254037844387, + "xy": 0.49999999999999994, + "yx": -0.49999999999999994, + "yy": 0.8660254037844387, + "dx": 281.69872981077805, + "dy": 231.69872981077808 + }, + "fill": { + "r": 0, + "g": 0, + "b": 255, + "a": 1 + }, + name: "blue rect" + }, + { + "shape": { + "type": "path", + "path": "M 300 100L 400 200L 400 300L 300 400C 400 300 400 200 300 100" + }, + "transform": { + "xx": 1, + "xy": 0, + "yx": 0, + "yy": 1, + "dx": 0, + "dy": 0 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 0, + "a": 1 + }, + "style": "solid", + "width": 1, + "cap": "butt", + "join": 4 + }, + name: "black path" + }, + { + "shape": { + "type": "path", + "path": "M 300 100L 400 200L 400 300L 300 400C 400 300 400 200 300 100" + }, + "transform": { + "dx": 100, + "xx": 1, + "xy": 0, + "yx": 0, + "yy": 1, + "dy": 0 + }, + "stroke": { + "type": "stroke", + "color": { + "g": 0, + "b": 0, + "r": 255, + "a": 1 + }, + "style": "solid", + "width": 2, + "cap": "butt", + "join": 4 + }, + name: "red path" + }, + { + "shape": { + "type": "path", + "path": "M 300 100l 100 100l 0 100l-100 100c 100-100 100-200 0-300" + }, + "transform": { + "xx": -1, + "xy": -1.2246063538223773e-16, + "yx": 1.2246063538223773e-16, + "yy": -1, + "dx": 500, + "dy": 500 + }, + "stroke": { + "type": "stroke", + "color": { + "r": 0, + "g": 0, + "b": 255, + "a": 1 + }, + "style": "solid", + "width": 2, + "cap": "butt", + "join": 4 + }, + name: "blue path" + } + ], + "transform": { + "xx": 0.9659258262890683, + "xy": 0.25881904510252074, + "yx": -0.25881904510252074, + "yy": 0.9659258262890683, + "dx": -56.1862178478973, + "dy": 73.22330470336311 + }, + "name": "rotated group" + } +] diff --git a/includes/js/dojox/gfx/demos/images/clock_face.jpg b/includes/js/dojox/gfx/demos/images/clock_face.jpg new file mode 100644 index 0000000..12f1903 Binary files /dev/null and b/includes/js/dojox/gfx/demos/images/clock_face.jpg differ diff --git a/includes/js/dojox/gfx/demos/images/clock_face_black.jpg b/includes/js/dojox/gfx/demos/images/clock_face_black.jpg new file mode 100644 index 0000000..dbef7cd Binary files /dev/null and b/includes/js/dojox/gfx/demos/images/clock_face_black.jpg differ diff --git a/includes/js/dojox/gfx/demos/inspector.html b/includes/js/dojox/gfx/demos/inspector.html new file mode 100644 index 0000000..034fa3b --- /dev/null +++ b/includes/js/dojox/gfx/demos/inspector.html @@ -0,0 +1,165 @@ + + +Inspect DojoX GFX JSON + + + + + + + +

Inspect DojoX GFX JSON

+

Help: load a file, select an object, and add it, move it around, or apply operations to selected items:
+ F — bring to front, B — bring to back, Q — rotate CCW, W — rotate CW, D — delete.
+ (all operations work on currently dragged item).

+

VML note: VML doesn't process PNG images with opacity correctly.

+ + + +
+ + + + + + + + + + + + + +
Source:
 
+  
Available sources:
data/Lars.json — vectors from SVG
data/Nils.json — vectors from SVG
data/LarsDreaming.json — vectors from SVG
data/buratino.json — images
data/transform.json — from dojox.gfx
 
Objects:
Object names are hierarchical and separated by "/". Adding a selected object creates a group for this object. + A higher-level object (a group) always includes lower-level objects as children.
+ + diff --git a/includes/js/dojox/gfx/demos/lion.html b/includes/js/dojox/gfx/demos/lion.html new file mode 100644 index 0000000..445945c --- /dev/null +++ b/includes/js/dojox/gfx/demos/lion.html @@ -0,0 +1,235 @@ + + +dojox.gfx: Lion + + + + + + + + + + + + + +

dojox.gfx: Lion

+

This example was directly converted from SVG file.

+ + + + + +
Rotation (0)
+
+
+
+
+
+
Scaling (1.000)
+
+
+
+
+
+
+ + diff --git a/includes/js/dojox/gfx/demos/roundedPane.html b/includes/js/dojox/gfx/demos/roundedPane.html new file mode 100644 index 0000000..4abb775 --- /dev/null +++ b/includes/js/dojox/gfx/demos/roundedPane.html @@ -0,0 +1,191 @@ + + + + + rounded skeleton page | The Dojo Toolkit + + + + + + + + + + +

Some gfx + ContentPane's

+ +
+

YO!

+

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

lorem

+
+ +
+ LOREM, ipsum, dollllllllllor: + .roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

.roundedContent { + padding: 31px; + font-family: 'Tahoma'; + font-size: 12px; + color:#fff; + }

+ +
+ + +
+

Moveable Handle

+ LOREM, ipsum, dollllllllllor: +
+ + +
+ lorem ipsum (small moveable) +
+ + + diff --git a/includes/js/dojox/gfx/demos/tiger.html b/includes/js/dojox/gfx/demos/tiger.html new file mode 100644 index 0000000..afb45ef --- /dev/null +++ b/includes/js/dojox/gfx/demos/tiger.html @@ -0,0 +1,566 @@ + + +dojox.gfx: Tiger + + + + + + + + +

dojox.gfx: Tiger

+

This example was directly converted from SVG file.

+ + + + + +
Rotation (0)
+
+
+
+
+
+
Scaling (1.000)
+
+
+
+
+
+
+ + diff --git a/includes/js/dojox/gfx/demos/tooltip.html b/includes/js/dojox/gfx/demos/tooltip.html new file mode 100644 index 0000000..96bb694 --- /dev/null +++ b/includes/js/dojox/gfx/demos/tooltip.html @@ -0,0 +1,238 @@ + + + A Sample ToolTip using dijit and dojox.gfx + + + + + + + + + +

dojox.gfx: A Sample tooltip

+ + + + +
Canvas renderer doesn't implement event handling. (shared tooltip)
+ + + diff --git a/includes/js/dojox/gfx/fx.js b/includes/js/dojox/gfx/fx.js new file mode 100644 index 0000000..2b576d6 --- /dev/null +++ b/includes/js/dojox/gfx/fx.js @@ -0,0 +1,281 @@ +if(!dojo._hasResource["dojox.gfx.fx"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.fx"] = true; +dojo.provide("dojox.gfx.fx"); + +dojo.require("dojox.gfx.matrix"); + +(function(){ + var d = dojo, g = dojox.gfx, m = g.matrix; + + // Generic interpolators. Should they be moved to dojox.fx? + + var InterpolNumber = function(start, end){ + this.start = start, this.end = end; + }; + d.extend(InterpolNumber, { + getValue: function(r){ + return (this.end - this.start) * r + this.start; + } + }); + + var InterpolUnit = function(start, end, unit){ + this.start = start, this.end = end; + this.unit = unit; + }; + d.extend(InterpolUnit, { + getValue: function(r){ + return (this.end - this.start) * r + this.start + this.unit; + } + }); + + var InterpolColor = function(start, end){ + this.start = start, this.end = end; + this.temp = new dojo.Color(); + }; + d.extend(InterpolColor, { + getValue: function(r){ + return d.blendColors(this.start, this.end, r, this.temp); + } + }); + + var InterpolValues = function(values){ + this.values = values; + this.length = values.length; + }; + d.extend(InterpolValues, { + getValue: function(r){ + return this.values[Math.min(Math.floor(r * this.length), this.length - 1)]; + } + }); + + var InterpolObject = function(values, def){ + this.values = values; + this.def = def ? def : {}; + }; + d.extend(InterpolObject, { + getValue: function(r){ + var ret = dojo.clone(this.def); + for(var i in this.values){ + ret[i] = this.values[i].getValue(r); + } + return ret; + } + }); + + var InterpolTransform = function(stack, original){ + this.stack = stack; + this.original = original; + }; + d.extend(InterpolTransform, { + getValue: function(r){ + var ret = []; + dojo.forEach(this.stack, function(t){ + if(t instanceof m.Matrix2D){ + ret.push(t); + return; + } + if(t.name == "original" && this.original){ + ret.push(this.original); + return; + } + if(!(t.name in m)){ return; } + var f = m[t.name]; + if(typeof f != "function"){ + // constant + ret.push(f); + return; + } + var val = dojo.map(t.start, function(v, i){ + return (t.end[i] - v) * r + v; + }), + matrix = f.apply(m, val); + if(matrix instanceof m.Matrix2D){ + ret.push(matrix); + } + }, this); + return ret; + } + }); + + var transparent = new d.Color(0, 0, 0, 0); + + var getColorInterpol = function(prop, obj, name, def){ + if(prop.values){ + return new InterpolValues(prop.values); + } + var value, start, end; + if(prop.start){ + start = g.normalizeColor(prop.start); + }else{ + start = value = obj ? (name ? obj[name] : obj) : def; + } + if(prop.end){ + end = g.normalizeColor(prop.end); + }else{ + if(!value){ + value = obj ? (name ? obj[name] : obj) : def; + } + end = value; + } + return new InterpolColor(start, end); + }; + + var getNumberInterpol = function(prop, obj, name, def){ + if(prop.values){ + return new InterpolValues(prop.values); + } + var value, start, end; + if(prop.start){ + start = prop.start; + }else{ + start = value = obj ? obj[name] : def; + } + if(prop.end){ + end = prop.end; + }else{ + if(typeof value != "number"){ + value = obj ? obj[name] : def; + } + end = value; + } + return new InterpolNumber(start, end); + }; + + g.fx.animateStroke = function(/*Object*/ args){ + // summary: + // returns the animation, which will change stroke properties over time + // example: + // | dojox.gfx.fx.animateStroke{{ + // | shape: shape, + // | duration: 500, + // | color: {start: "red", end: "green"}, + // | width: {end: 15}, + // | join: {values: ["miter", "bevel", "round"]} + // | }).play(); + if(!args.easing){ args.easing = d._defaultEasing; } + var anim = new d._Animation(args), shape = args.shape, stroke; + d.connect(anim, "beforeBegin", anim, function(){ + stroke = shape.getStroke(); + var prop = args.color, values = {}, value, start, end; + if(prop){ + values.color = getColorInterpol(prop, stroke, "color", transparent); + } + prop = args.style; + if(prop && prop.values){ + values.style = new InterpolValues(prop.values); + } + prop = args.width; + if(prop){ + values.width = getNumberInterpol(prop, stroke, "width", 1); + } + prop = args.cap; + if(prop && prop.values){ + values.cap = new InterpolValues(prop.values); + } + prop = args.join; + if(prop){ + if(prop.values){ + values.join = new InterpolValues(prop.values); + }else{ + start = prop.start ? prop.start : (stroke && stroke.join || 0); + end = prop.end ? prop.end : (stroke && stroke.join || 0); + if(typeof start == "number" && typeof end == "number"){ + values.join = new InterpolNumber(start, end); + } + } + } + this.curve = new InterpolObject(values, stroke); + }); + d.connect(anim, "onAnimate", shape, "setStroke"); + return anim; + }; + + g.fx.animateFill = function(/*Object*/ args){ + // summary: + // returns the animation, which will change fill color over time, + // only solid fill color is supported at the moment + // example: + // | dojox.gfx.fx.animateFill{{ + // | shape: shape, + // | duration: 500, + // | color: {start: "red", end: "green"} + // | }).play(); + if(!args.easing){ args.easing = d._defaultEasing; } + var anim = new d._Animation(args), shape = args.shape, fill; + d.connect(anim, "beforeBegin", anim, function(){ + fill = shape.getFill(); + var prop = args.color, values = {}; + if(prop){ + this.curve = getColorInterpol(prop, fill, "", transparent); + } + }); + d.connect(anim, "onAnimate", shape, "setFill"); + return anim; + }; + + g.fx.animateFont = function(/*Object*/ args){ + // summary: + // returns the animation, which will change font properties over time + // example: + // | dojox.gfx.fx.animateFont{{ + // | shape: shape, + // | duration: 500, + // | variant: {values: ["normal", "small-caps"]}, + // | size: {end: 10, unit: "pt"} + // | }).play(); + if(!args.easing){ args.easing = d._defaultEasing; } + var anim = new d._Animation(args), shape = args.shape, font; + d.connect(anim, "beforeBegin", anim, function(){ + font = shape.getFont(); + var prop = args.style, values = {}, value, start, end; + if(prop && prop.values){ + values.style = new InterpolValues(prop.values); + } + prop = args.variant; + if(prop && prop.values){ + values.variant = new InterpolValues(prop.values); + } + prop = args.weight; + if(prop && prop.values){ + values.weight = new InterpolValues(prop.values); + } + prop = args.family; + if(prop && prop.values){ + values.family = new InterpolValues(prop.values); + } + prop = args.size; + if(prop && prop.unit){ + start = parseFloat(prop.start ? prop.start : (shape.font && shape.font.size || "0")); + end = parseFloat(prop.end ? prop.end : (shape.font && shape.font.size || "0")); + values.size = new InterpolUnit(start, end, prop.unit); + } + this.curve = new InterpolObject(values, font); + }); + d.connect(anim, "onAnimate", shape, "setFont"); + return anim; + }; + + g.fx.animateTransform = function(/*Object*/ args){ + // summary: + // returns the animation, which will change transformation over time + // example: + // | dojox.gfx.fx.animateTransform{{ + // | shape: shape, + // | duration: 500, + // | transform: [ + // | {name: "translate", start: [0, 0], end: [200, 200]}, + // | {name: "original"} + // | ] + // | }).play(); + if(!args.easing){ args.easing = d._defaultEasing; } + var anim = new d._Animation(args), shape = args.shape, original; + d.connect(anim, "beforeBegin", anim, function(){ + original = shape.getTransform(); + this.curve = new InterpolTransform(args.transform, original); + }); + d.connect(anim, "onAnimate", shape, "setTransform"); + return anim; + }; +})(); + +} diff --git a/includes/js/dojox/gfx/matrix.js b/includes/js/dojox/gfx/matrix.js new file mode 100644 index 0000000..f3402b1 --- /dev/null +++ b/includes/js/dojox/gfx/matrix.js @@ -0,0 +1,444 @@ +if(!dojo._hasResource["dojox.gfx.matrix"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.matrix"] = true; +dojo.provide("dojox.gfx.matrix"); + +(function(){ + var m = dojox.gfx.matrix; + + // candidates for dojox.math: + m._degToRad = function(degree){ return Math.PI * degree / 180; }; + m._radToDeg = function(radian){ return radian / Math.PI * 180; }; + + m.Matrix2D = function(arg){ + // summary: a 2D matrix object + // description: Normalizes a 2D matrix-like object. If arrays is passed, + // all objects of the array are normalized and multiplied sequentially. + // arg: Object + // a 2D matrix-like object, a number, or an array of such objects + if(arg){ + if(typeof arg == "number"){ + this.xx = this.yy = arg; + }else if(arg instanceof Array){ + if(arg.length > 0){ + var matrix = m.normalize(arg[0]); + // combine matrices + for(var i = 1; i < arg.length; ++i){ + var l = matrix, r = dojox.gfx.matrix.normalize(arg[i]); + matrix = new m.Matrix2D(); + matrix.xx = l.xx * r.xx + l.xy * r.yx; + matrix.xy = l.xx * r.xy + l.xy * r.yy; + matrix.yx = l.yx * r.xx + l.yy * r.yx; + matrix.yy = l.yx * r.xy + l.yy * r.yy; + matrix.dx = l.xx * r.dx + l.xy * r.dy + l.dx; + matrix.dy = l.yx * r.dx + l.yy * r.dy + l.dy; + } + dojo.mixin(this, matrix); + } + }else{ + dojo.mixin(this, arg); + } + } + }; + + // the default (identity) matrix, which is used to fill in missing values + dojo.extend(m.Matrix2D, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0}); + + dojo.mixin(m, { + // summary: class constants, and methods of dojox.gfx.matrix + + // matrix constants + + // identity: dojox.gfx.matrix.Matrix2D + // an identity matrix constant: identity * (x, y) == (x, y) + identity: new m.Matrix2D(), + + // flipX: dojox.gfx.matrix.Matrix2D + // a matrix, which reflects points at x = 0 line: flipX * (x, y) == (-x, y) + flipX: new m.Matrix2D({xx: -1}), + + // flipY: dojox.gfx.matrix.Matrix2D + // a matrix, which reflects points at y = 0 line: flipY * (x, y) == (x, -y) + flipY: new m.Matrix2D({yy: -1}), + + // flipXY: dojox.gfx.matrix.Matrix2D + // a matrix, which reflects points at the origin of coordinates: flipXY * (x, y) == (-x, -y) + flipXY: new m.Matrix2D({xx: -1, yy: -1}), + + // matrix creators + + translate: function(a, b){ + // summary: forms a translation matrix + // description: The resulting matrix is used to translate (move) points by specified offsets. + // a: Number: an x coordinate value + // b: Number: a y coordinate value + if(arguments.length > 1){ + return new m.Matrix2D({dx: a, dy: b}); // dojox.gfx.matrix.Matrix2D + } + // branch + // a: dojox.gfx.Point: a point-like object, which specifies offsets for both dimensions + // b: null + return new m.Matrix2D({dx: a.x, dy: a.y}); // dojox.gfx.matrix.Matrix2D + }, + scale: function(a, b){ + // summary: forms a scaling matrix + // description: The resulting matrix is used to scale (magnify) points by specified offsets. + // a: Number: a scaling factor used for the x coordinate + // b: Number: a scaling factor used for the y coordinate + if(arguments.length > 1){ + return new m.Matrix2D({xx: a, yy: b}); // dojox.gfx.matrix.Matrix2D + } + if(typeof a == "number"){ + // branch + // a: Number: a uniform scaling factor used for the both coordinates + // b: null + return new m.Matrix2D({xx: a, yy: a}); // dojox.gfx.matrix.Matrix2D + } + // branch + // a: dojox.gfx.Point: a point-like object, which specifies scale factors for both dimensions + // b: null + return new m.Matrix2D({xx: a.x, yy: a.y}); // dojox.gfx.matrix.Matrix2D + }, + rotate: function(angle){ + // summary: forms a rotating matrix + // description: The resulting matrix is used to rotate points + // around the origin of coordinates (0, 0) by specified angle. + // angle: Number: an angle of rotation in radians (>0 for CW) + var c = Math.cos(angle); + var s = Math.sin(angle); + return new m.Matrix2D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx.matrix.Matrix2D + }, + rotateg: function(degree){ + // summary: forms a rotating matrix + // description: The resulting matrix is used to rotate points + // around the origin of coordinates (0, 0) by specified degree. + // See dojox.gfx.matrix.rotate() for comparison. + // degree: Number: an angle of rotation in degrees (>0 for CW) + return m.rotate(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D + }, + skewX: function(angle) { + // summary: forms an x skewing matrix + // description: The resulting matrix is used to skew points in the x dimension + // around the origin of coordinates (0, 0) by specified angle. + // angle: Number: an skewing angle in radians + return new m.Matrix2D({xy: -Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D + }, + skewXg: function(degree){ + // summary: forms an x skewing matrix + // description: The resulting matrix is used to skew points in the x dimension + // around the origin of coordinates (0, 0) by specified degree. + // See dojox.gfx.matrix.skewX() for comparison. + // degree: Number: an skewing angle in degrees + return m.skewX(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D + }, + skewY: function(angle){ + // summary: forms a y skewing matrix + // description: The resulting matrix is used to skew points in the y dimension + // around the origin of coordinates (0, 0) by specified angle. + // angle: Number: an skewing angle in radians + return new m.Matrix2D({yx: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D + }, + skewYg: function(degree){ + // summary: forms a y skewing matrix + // description: The resulting matrix is used to skew points in the y dimension + // around the origin of coordinates (0, 0) by specified degree. + // See dojox.gfx.matrix.skewY() for comparison. + // degree: Number: an skewing angle in degrees + return m.skewY(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D + }, + reflect: function(a, b){ + // summary: forms a reflection matrix + // description: The resulting matrix is used to reflect points around a vector, + // which goes through the origin. + // a: dojox.gfx.Point: a point-like object, which specifies a vector of reflection + // b: null + if(arguments.length == 1){ + b = a.y; + a = a.x; + } + // branch + // a: Number: an x coordinate value + // b: Number: a y coordinate value + + // make a unit vector + var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = 2 * a * b / n2; + return new m.Matrix2D({xx: 2 * a2 / n2 - 1, xy: xy, yx: xy, yy: 2 * b2 / n2 - 1}); // dojox.gfx.matrix.Matrix2D + }, + project: function(a, b){ + // summary: forms an orthogonal projection matrix + // description: The resulting matrix is used to project points orthogonally on a vector, + // which goes through the origin. + // a: dojox.gfx.Point: a point-like object, which specifies a vector of projection + // b: null + if(arguments.length == 1){ + b = a.y; + a = a.x; + } + // branch + // a: Number: an x coordinate value + // b: Number: a y coordinate value + + // make a unit vector + var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = a * b / n2; + return new m.Matrix2D({xx: a2 / n2, xy: xy, yx: xy, yy: b2 / n2}); // dojox.gfx.matrix.Matrix2D + }, + + // ensure matrix 2D conformance + normalize: function(matrix){ + // summary: converts an object to a matrix, if necessary + // description: Converts any 2D matrix-like object or an array of + // such objects to a valid dojox.gfx.matrix.Matrix2D object. + // matrix: Object: an object, which is converted to a matrix, if necessary + return (matrix instanceof m.Matrix2D) ? matrix : new m.Matrix2D(matrix); // dojox.gfx.matrix.Matrix2D + }, + + // common operations + + clone: function(matrix){ + // summary: creates a copy of a 2D matrix + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be cloned + var obj = new m.Matrix2D(); + for(var i in matrix){ + if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i]; + } + return obj; // dojox.gfx.matrix.Matrix2D + }, + invert: function(matrix){ + // summary: inverts a 2D matrix + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be inverted + var M = m.normalize(matrix), + D = M.xx * M.yy - M.xy * M.yx, + M = new m.Matrix2D({ + xx: M.yy/D, xy: -M.xy/D, + yx: -M.yx/D, yy: M.xx/D, + dx: (M.xy * M.dy - M.yy * M.dx) / D, + dy: (M.yx * M.dx - M.xx * M.dy) / D + }); + return M; // dojox.gfx.matrix.Matrix2D + }, + _multiplyPoint: function(matrix, x, y){ + // summary: applies a matrix to a point + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied + // x: Number: an x coordinate of a point + // y: Number: a y coordinate of a point + return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y: matrix.yx * x + matrix.yy * y + matrix.dy}; // dojox.gfx.Point + }, + multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b){ + // summary: applies a matrix to a point + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied + // a: Number: an x coordinate of a point + // b: Number: a y coordinate of a point + var M = m.normalize(matrix); + if(typeof a == "number" && typeof b == "number"){ + return m._multiplyPoint(M, a, b); // dojox.gfx.Point + } + // branch + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied + // a: dojox.gfx.Point: a point + // b: null + return m._multiplyPoint(M, a.x, a.y); // dojox.gfx.Point + }, + multiply: function(matrix){ + // summary: combines matrices by multiplying them sequentially in the given order + // matrix: dojox.gfx.matrix.Matrix2D...: a 2D matrix-like object, + // all subsequent arguments are matrix-like objects too + var M = m.normalize(matrix); + // combine matrices + for(var i = 1; i < arguments.length; ++i){ + var l = M, r = m.normalize(arguments[i]); + M = new m.Matrix2D(); + M.xx = l.xx * r.xx + l.xy * r.yx; + M.xy = l.xx * r.xy + l.xy * r.yy; + M.yx = l.yx * r.xx + l.yy * r.yx; + M.yy = l.yx * r.xy + l.yy * r.yy; + M.dx = l.xx * r.dx + l.xy * r.dy + l.dx; + M.dy = l.yx * r.dx + l.yy * r.dy + l.dy; + } + return M; // dojox.gfx.matrix.Matrix2D + }, + + // high level operations + + _sandwich: function(matrix, x, y){ + // summary: applies a matrix at a centrtal point + // matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object, which is applied at a central point + // x: Number: an x component of the central point + // y: Number: a y component of the central point + return m.multiply(m.translate(x, y), matrix, m.translate(-x, -y)); // dojox.gfx.matrix.Matrix2D + }, + scaleAt: function(a, b, c, d){ + // summary: scales a picture using a specified point as a center of scaling + // description: Compare with dojox.gfx.matrix.scale(). + // a: Number: a scaling factor used for the x coordinate + // b: Number: a scaling factor used for the y coordinate + // c: Number: an x component of a central point + // d: Number: a y component of a central point + + // accepts several signatures: + // 1) uniform scale factor, Point + // 2) uniform scale factor, x, y + // 3) x scale, y scale, Point + // 4) x scale, y scale, x, y + + switch(arguments.length){ + case 4: + // a and b are scale factor components, c and d are components of a point + return m._sandwich(m.scale(a, b), c, d); // dojox.gfx.matrix.Matrix2D + case 3: + if(typeof c == "number"){ + // branch + // a: Number: a uniform scaling factor used for both coordinates + // b: Number: an x component of a central point + // c: Number: a y component of a central point + // d: null + return m._sandwich(m.scale(a), b, c); // dojox.gfx.matrix.Matrix2D + } + // branch + // a: Number: a scaling factor used for the x coordinate + // b: Number: a scaling factor used for the y coordinate + // c: dojox.gfx.Point: a central point + // d: null + return m._sandwich(m.scale(a, b), c.x, c.y); // dojox.gfx.matrix.Matrix2D + } + // branch + // a: Number: a uniform scaling factor used for both coordinates + // b: dojox.gfx.Point: a central point + // c: null + // d: null + return m._sandwich(m.scale(a), b.x, b.y); // dojox.gfx.matrix.Matrix2D + }, + rotateAt: function(angle, a, b){ + // summary: rotates a picture using a specified point as a center of rotation + // description: Compare with dojox.gfx.matrix.rotate(). + // angle: Number: an angle of rotation in radians (>0 for CW) + // a: Number: an x component of a central point + // b: Number: a y component of a central point + + // accepts several signatures: + // 1) rotation angle in radians, Point + // 2) rotation angle in radians, x, y + + if(arguments.length > 2){ + return m._sandwich(m.rotate(angle), a, b); // dojox.gfx.matrix.Matrix2D + } + + // branch + // angle: Number: an angle of rotation in radians (>0 for CCW) + // a: dojox.gfx.Point: a central point + // b: null + return m._sandwich(m.rotate(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D + }, + rotategAt: function(degree, a, b){ + // summary: rotates a picture using a specified point as a center of rotation + // description: Compare with dojox.gfx.matrix.rotateg(). + // degree: Number: an angle of rotation in degrees (>0 for CW) + // a: Number: an x component of a central point + // b: Number: a y component of a central point + + // accepts several signatures: + // 1) rotation angle in degrees, Point + // 2) rotation angle in degrees, x, y + + if(arguments.length > 2){ + return m._sandwich(m.rotateg(degree), a, b); // dojox.gfx.matrix.Matrix2D + } + + // branch + // degree: Number: an angle of rotation in degrees (>0 for CCW) + // a: dojox.gfx.Point: a central point + // b: null + return m._sandwich(m.rotateg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D + }, + skewXAt: function(angle, a, b){ + // summary: skews a picture along the x axis using a specified point as a center of skewing + // description: Compare with dojox.gfx.matrix.skewX(). + // angle: Number: an skewing angle in radians + // a: Number: an x component of a central point + // b: Number: a y component of a central point + + // accepts several signatures: + // 1) skew angle in radians, Point + // 2) skew angle in radians, x, y + + if(arguments.length > 2){ + return m._sandwich(m.skewX(angle), a, b); // dojox.gfx.matrix.Matrix2D + } + + // branch + // angle: Number: an skewing angle in radians + // a: dojox.gfx.Point: a central point + // b: null + return m._sandwich(m.skewX(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D + }, + skewXgAt: function(degree, a, b){ + // summary: skews a picture along the x axis using a specified point as a center of skewing + // description: Compare with dojox.gfx.matrix.skewXg(). + // degree: Number: an skewing angle in degrees + // a: Number: an x component of a central point + // b: Number: a y component of a central point + + // accepts several signatures: + // 1) skew angle in degrees, Point + // 2) skew angle in degrees, x, y + + if(arguments.length > 2){ + return m._sandwich(m.skewXg(degree), a, b); // dojox.gfx.matrix.Matrix2D + } + + // branch + // degree: Number: an skewing angle in degrees + // a: dojox.gfx.Point: a central point + // b: null + return m._sandwich(m.skewXg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D + }, + skewYAt: function(angle, a, b){ + // summary: skews a picture along the y axis using a specified point as a center of skewing + // description: Compare with dojox.gfx.matrix.skewY(). + // angle: Number: an skewing angle in radians + // a: Number: an x component of a central point + // b: Number: a y component of a central point + + // accepts several signatures: + // 1) skew angle in radians, Point + // 2) skew angle in radians, x, y + + if(arguments.length > 2){ + return m._sandwich(m.skewY(angle), a, b); // dojox.gfx.matrix.Matrix2D + } + + // branch + // angle: Number: an skewing angle in radians + // a: dojox.gfx.Point: a central point + // b: null + return m._sandwich(m.skewY(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D + }, + skewYgAt: function(/* Number */ degree, /* Number||Point */ a, /* Number, optional */ b){ + // summary: skews a picture along the y axis using a specified point as a center of skewing + // description: Compare with dojox.gfx.matrix.skewYg(). + // degree: Number: an skewing angle in degrees + // a: Number: an x component of a central point + // b: Number: a y component of a central point + + // accepts several signatures: + // 1) skew angle in degrees, Point + // 2) skew angle in degrees, x, y + + if(arguments.length > 2){ + return m._sandwich(m.skewYg(degree), a, b); // dojox.gfx.matrix.Matrix2D + } + + // branch + // degree: Number: an skewing angle in degrees + // a: dojox.gfx.Point: a central point + // b: null + return m._sandwich(m.skewYg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D + } + + //TODO: rect-to-rect mapping, scale-to-fit (isotropic and anisotropic versions) + + }); +})(); + +// propagate Matrix2D up +dojox.gfx.Matrix2D = dojox.gfx.matrix.Matrix2D; + +} diff --git a/includes/js/dojox/gfx/move.js b/includes/js/dojox/gfx/move.js new file mode 100644 index 0000000..dba5ced --- /dev/null +++ b/includes/js/dojox/gfx/move.js @@ -0,0 +1,8 @@ +if(!dojo._hasResource["dojox.gfx.move"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.move"] = true; +dojo.provide("dojox.gfx.move"); + +dojo.require("dojox.gfx.Mover"); +dojo.require("dojox.gfx.Moveable"); + +} diff --git a/includes/js/dojox/gfx/path.js b/includes/js/dojox/gfx/path.js new file mode 100644 index 0000000..657136b --- /dev/null +++ b/includes/js/dojox/gfx/path.js @@ -0,0 +1,361 @@ +if(!dojo._hasResource["dojox.gfx.path"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.path"] = true; +dojo.provide("dojox.gfx.path"); + +dojo.require("dojox.gfx.shape"); + +dojo.declare("dojox.gfx.path.Path", dojox.gfx.Shape, { + // summary: a generalized path shape + + constructor: function(rawNode){ + // summary: a path constructor + // rawNode: Node: a DOM node to be used by this path object + this.shape = dojo.clone(dojox.gfx.defaultPath); + this.segments = []; + this.absolute = true; + this.last = {}; + this.rawNode = rawNode; + }, + + // mode manipulations + setAbsoluteMode: function(mode){ + // summary: sets an absolute or relative mode for path points + // mode: Boolean: true/false or "absolute"/"relative" to specify the mode + this.absolute = typeof mode == "string" ? (mode == "absolute") : mode; + return this; // self + }, + getAbsoluteMode: function(){ + // summary: returns a current value of the absolute mode + return this.absolute; // Boolean + }, + + getBoundingBox: function(){ + // summary: returns the bounding box {x, y, width, height} or null + return (this.bbox && ("l" in this.bbox)) ? {x: this.bbox.l, y: this.bbox.t, width: this.bbox.r - this.bbox.l, height: this.bbox.b - this.bbox.t} : null; // dojox.gfx.Rectangle + }, + + getLastPosition: function(){ + // summary: returns the last point in the path, or null + return "x" in this.last ? this.last : null; // Object + }, + + // segment interpretation + _updateBBox: function(x, y){ + // summary: updates the bounding box of path with new point + // x: Number: an x coordinate + // y: Number: a y coordinate + + // we use {l, b, r, t} representation of a bbox + if(this.bbox && ("l" in this.bbox)){ + if(this.bbox.l > x) this.bbox.l = x; + if(this.bbox.r < x) this.bbox.r = x; + if(this.bbox.t > y) this.bbox.t = y; + if(this.bbox.b < y) this.bbox.b = y; + }else{ + this.bbox = {l: x, b: y, r: x, t: y}; + } + }, + _updateWithSegment: function(segment){ + // summary: updates the bounding box of path with new segment + // segment: Object: a segment + var n = segment.args, l = n.length; + // update internal variables: bbox, absolute, last + switch(segment.action){ + case "M": + case "L": + case "C": + case "S": + case "Q": + case "T": + for(var i = 0; i < l; i += 2){ + this._updateBBox(n[i], n[i + 1]); + } + this.last.x = n[l - 2]; + this.last.y = n[l - 1]; + this.absolute = true; + break; + case "H": + for(var i = 0; i < l; ++i){ + this._updateBBox(n[i], this.last.y); + } + this.last.x = n[l - 1]; + this.absolute = true; + break; + case "V": + for(var i = 0; i < l; ++i){ + this._updateBBox(this.last.x, n[i]); + } + this.last.y = n[l - 1]; + this.absolute = true; + break; + case "m": + var start = 0; + if(!("x" in this.last)){ + this._updateBBox(this.last.x = n[0], this.last.y = n[1]); + start = 2; + } + for(var i = start; i < l; i += 2){ + this._updateBBox(this.last.x += n[i], this.last.y += n[i + 1]); + } + this.absolute = false; + break; + case "l": + case "t": + for(var i = 0; i < l; i += 2){ + this._updateBBox(this.last.x += n[i], this.last.y += n[i + 1]); + } + this.absolute = false; + break; + case "h": + for(var i = 0; i < l; ++i){ + this._updateBBox(this.last.x += n[i], this.last.y); + } + this.absolute = false; + break; + case "v": + for(var i = 0; i < l; ++i){ + this._updateBBox(this.last.x, this.last.y += n[i]); + } + this.absolute = false; + break; + case "c": + for(var i = 0; i < l; i += 6){ + this._updateBBox(this.last.x + n[i], this.last.y + n[i + 1]); + this._updateBBox(this.last.x + n[i + 2], this.last.y + n[i + 3]); + this._updateBBox(this.last.x += n[i + 4], this.last.y += n[i + 5]); + } + this.absolute = false; + break; + case "s": + case "q": + for(var i = 0; i < l; i += 4){ + this._updateBBox(this.last.x + n[i], this.last.y + n[i + 1]); + this._updateBBox(this.last.x += n[i + 2], this.last.y += n[i + 3]); + } + this.absolute = false; + break; + case "A": + for(var i = 0; i < l; i += 7){ + this._updateBBox(n[i + 5], n[i + 6]); + } + this.last.x = n[l - 2]; + this.last.y = n[l - 1]; + this.absolute = true; + break; + case "a": + for(var i = 0; i < l; i += 7){ + this._updateBBox(this.last.x += n[i + 5], this.last.y += n[i + 6]); + } + this.absolute = false; + break; + } + // add an SVG path segment + var path = [segment.action]; + for(var i = 0; i < l; ++i){ + path.push(dojox.gfx.formatNumber(n[i], true)); + } + if(typeof this.shape.path == "string"){ + this.shape.path += path.join(""); + }else{ + var l = path.length, a = this.shape.path; + for(var i = 0; i < l; ++i){ + a.push(path[i]); + } + } + }, + + // a dictionary, which maps segment type codes to a number of their argemnts + _validSegments: {m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7, z: 0}, + + _pushSegment: function(action, args){ + // summary: adds a segment + // action: String: valid SVG code for a segment's type + // args: Array: a list of parameters for this segment + var group = this._validSegments[action.toLowerCase()]; + if(typeof group == "number"){ + if(group){ + if(args.length >= group){ + var segment = {action: action, args: args.slice(0, args.length - args.length % group)}; + this.segments.push(segment); + this._updateWithSegment(segment); + } + }else{ + var segment = {action: action, args: []}; + this.segments.push(segment); + this._updateWithSegment(segment); + } + } + }, + + _collectArgs: function(array, args){ + // summary: converts an array of arguments to plain numeric values + // array: Array: an output argument (array of numbers) + // args: Array: an input argument (can be values of Boolean, Number, dojox.gfx.Point, or an embedded array of them) + for(var i = 0; i < args.length; ++i){ + var t = args[i]; + if(typeof t == "boolean"){ + array.push(t ? 1 : 0); + }else if(typeof t == "number"){ + array.push(t); + }else if(t instanceof Array){ + this._collectArgs(array, t); + }else if("x" in t && "y" in t){ + array.push(t.x, t.y); + } + } + }, + + // segments + moveTo: function(){ + // summary: formes a move segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "M" : "m", args); + return this; // self + }, + lineTo: function(){ + // summary: formes a line segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "L" : "l", args); + return this; // self + }, + hLineTo: function(){ + // summary: formes a horizontal line segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "H" : "h", args); + return this; // self + }, + vLineTo: function(){ + // summary: formes a vertical line segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "V" : "v", args); + return this; // self + }, + curveTo: function(){ + // summary: formes a curve segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "C" : "c", args); + return this; // self + }, + smoothCurveTo: function(){ + // summary: formes a smooth curve segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "S" : "s", args); + return this; // self + }, + qCurveTo: function(){ + // summary: formes a quadratic curve segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "Q" : "q", args); + return this; // self + }, + qSmoothCurveTo: function(){ + // summary: formes a quadratic smooth curve segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "T" : "t", args); + return this; // self + }, + arcTo: function(){ + // summary: formes an elliptic arc segment + var args = []; + this._collectArgs(args, arguments); + this._pushSegment(this.absolute ? "A" : "a", args); + return this; // self + }, + closePath: function(){ + // summary: closes a path + this._pushSegment("Z", []); + return this; // self + }, + + // setShape + _setPath: function(path){ + // summary: forms a path using an SVG path string + // path: String: an SVG path string + var p = dojo.isArray(path) ? path : path.match(dojox.gfx.pathSvgRegExp); + this.segments = []; + this.absolute = true; + this.bbox = {}; + this.last = {}; + if(!p) return; + // create segments + var action = "", // current action + args = [], // current arguments + l = p.length; + for(var i = 0; i < l; ++i){ + var t = p[i], x = parseFloat(t); + if(isNaN(x)){ + if(action){ + this._pushSegment(action, args); + } + args = []; + action = t; + }else{ + args.push(x); + } + } + this._pushSegment(action, args); + }, + setShape: function(newShape){ + // summary: forms a path using a shape + // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath) + dojox.gfx.Shape.prototype.setShape.call(this, typeof newShape == "string" ? {path: newShape} : newShape); + var path = this.shape.path; + // switch to non-updating version of path building + this.shape.path = []; + this._setPath(path); + // switch back to the string path + this.shape.path = this.shape.path.join(""); + return this; // self + }, + + // useful constant for descendants + _2PI: Math.PI * 2 +}); + +dojo.declare("dojox.gfx.path.TextPath", dojox.gfx.path.Path, { + // summary: a generalized TextPath shape + + constructor: function(rawNode){ + // summary: a TextPath shape constructor + // rawNode: Node: a DOM node to be used by this TextPath object + if(!("text" in this)){ + this.text = dojo.clone(dojox.gfx.defaultTextPath); + } + if(!("fontStyle" in this)){ + this.fontStyle = dojo.clone(dojox.gfx.defaultFont); + } + }, + getText: function(){ + // summary: returns the current text object or null + return this.text; // Object + }, + setText: function(newText){ + // summary: sets a text to be drawn along the path + this.text = dojox.gfx.makeParameters(this.text, + typeof newText == "string" ? {text: newText} : newText); + this._setText(); + return this; // self + }, + getFont: function(){ + // summary: returns the current font object or null + return this.fontStyle; // Object + }, + setFont: function(newFont){ + // summary: sets a font for text + this.fontStyle = typeof newFont == "string" ? + dojox.gfx.splitFontString(newFont) : + dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont); + this._setFont(); + return this; // self + } +}); + +} diff --git a/includes/js/dojox/gfx/shape.js b/includes/js/dojox/gfx/shape.js new file mode 100644 index 0000000..179f6c5 --- /dev/null +++ b/includes/js/dojox/gfx/shape.js @@ -0,0 +1,691 @@ +if(!dojo._hasResource["dojox.gfx.shape"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.shape"] = true; +dojo.provide("dojox.gfx.shape"); + +dojo.require("dojox.gfx._base"); + +dojo.declare("dojox.gfx.Shape", null, { + // summary: a Shape object, which knows how to apply + // graphical attributes and transformations + + constructor: function(){ + // rawNode: Node: underlying node + this.rawNode = null; + + // shape: Object: an abstract shape object + // (see dojox.gfx.defaultPath, + // dojox.gfx.defaultPolyline, + // dojox.gfx.defaultRect, + // dojox.gfx.defaultEllipse, + // dojox.gfx.defaultCircle, + // dojox.gfx.defaultLine, + // or dojox.gfx.defaultImage) + this.shape = null; + + // matrix: dojox.gfx.Matrix2D: a transformation matrix + this.matrix = null; + + // fillStyle: Object: a fill object + // (see dojox.gfx.defaultLinearGradient, + // dojox.gfx.defaultRadialGradient, + // dojox.gfx.defaultPattern, + // or dojo.Color) + this.fillStyle = null; + + // strokeStyle: Object: a stroke object + // (see dojox.gfx.defaultStroke) + this.strokeStyle = null; + + // bbox: dojox.gfx.Rectangle: a bounding box of this shape + // (see dojox.gfx.defaultRect) + this.bbox = null; + + // virtual group structure + + // parent: Object: a parent or null + // (see dojox.gfx.Surface, + // dojox.gfx.shape.VirtualGroup, + // or dojox.gfx.Group) + this.parent = null; + + // parentMatrix: dojox.gfx.Matrix2D + // a transformation matrix inherited from the parent + this.parentMatrix = null; + }, + + // trivial getters + + getNode: function(){ + // summary: returns the current DOM Node or null + return this.rawNode; // Node + }, + getShape: function(){ + // summary: returns the current shape object or null + // (see dojox.gfx.defaultPath, + // dojox.gfx.defaultPolyline, + // dojox.gfx.defaultRect, + // dojox.gfx.defaultEllipse, + // dojox.gfx.defaultCircle, + // dojox.gfx.defaultLine, + // or dojox.gfx.defaultImage) + return this.shape; // Object + }, + getTransform: function(){ + // summary: returns the current transformation matrix or null + return this.matrix; // dojox.gfx.Matrix2D + }, + getFill: function(){ + // summary: returns the current fill object or null + // (see dojox.gfx.defaultLinearGradient, + // dojox.gfx.defaultRadialGradient, + // dojox.gfx.defaultPattern, + // or dojo.Color) + return this.fillStyle; // Object + }, + getStroke: function(){ + // summary: returns the current stroke object or null + // (see dojox.gfx.defaultStroke) + return this.strokeStyle; // Object + }, + getParent: function(){ + // summary: returns the parent or null + // (see dojox.gfx.Surface, + // dojox.gfx.shape.VirtualGroup, + // or dojox.gfx.Group) + return this.parent; // Object + }, + getBoundingBox: function(){ + // summary: returns the bounding box or null + // (see dojox.gfx.defaultRect) + return this.bbox; // dojox.gfx.Rectangle + }, + getTransformedBoundingBox: function(){ + // summary: returns an array of four points or null + // four points represent four corners of the untransformed bounding box + var b = this.getBoundingBox(); + if(!b){ + return null; // null + } + var m = this._getRealMatrix(); + var r = []; + var g = dojox.gfx.matrix; + r.push(g.multiplyPoint(m, b.x, b.y)); + r.push(g.multiplyPoint(m, b.x + b.width, b.y)); + r.push(g.multiplyPoint(m, b.x + b.width, b.y + b.height)); + r.push(g.multiplyPoint(m, b.x, b.y + b.height)); + return r; // Array + }, + getEventSource: function(){ + // summary: returns a Node, which is used as + // a source of events for this shape + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + + return this.rawNode; // Node + }, + + // empty settings + + setShape: function(shape){ + // summary: sets a shape object + // (the default implementation simply ignores it) + // shape: Object: a shape object + // (see dojox.gfx.defaultPath, + // dojox.gfx.defaultPolyline, + // dojox.gfx.defaultRect, + // dojox.gfx.defaultEllipse, + // dojox.gfx.defaultCircle, + // dojox.gfx.defaultLine, + // or dojox.gfx.defaultImage) + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + + this.shape = dojox.gfx.makeParameters(this.shape, shape); + this.bbox = null; + return this; // self + }, + setFill: function(fill){ + // summary: sets a fill object + // (the default implementation simply ignores it) + // fill: Object: a fill object + // (see dojox.gfx.defaultLinearGradient, + // dojox.gfx.defaultRadialGradient, + // dojox.gfx.defaultPattern, + // or dojo.Color) + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + + if(!fill){ + // don't fill + this.fillStyle = null; + return this; // self + } + var f = null; + if(typeof(fill) == "object" && "type" in fill){ + // gradient or pattern + switch(fill.type){ + case "linear": + f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill); + break; + case "radial": + f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill); + break; + case "pattern": + f = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill); + break; + } + }else{ + // color object + f = dojox.gfx.normalizeColor(fill); + } + this.fillStyle = f; + return this; // self + }, + setStroke: function(stroke){ + // summary: sets a stroke object + // (the default implementation simply ignores it) + // stroke: Object: a stroke object + // (see dojox.gfx.defaultStroke) + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + + if(!stroke){ + // don't stroke + this.strokeStyle = null; + return this; // self + } + // normalize the stroke + if(typeof stroke == "string"){ + stroke = {color: stroke}; + } + var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke); + s.color = dojox.gfx.normalizeColor(s.color); + return this; // self + }, + setTransform: function(matrix){ + // summary: sets a transformation matrix + // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object + // (see an argument of dojox.gfx.Matrix2D + // constructor for a list of acceptable arguments) + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + + this.matrix = dojox.gfx.matrix.clone(matrix ? dojox.gfx.matrix.normalize(matrix) : dojox.gfx.matrix.identity); + return this._applyTransform(); // self + }, + + _applyTransform: function(){ + // summary: physically sets a matrix + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + + return this; // self + }, + + // z-index + + moveToFront: function(){ + // summary: moves a shape to front of its parent's list of shapes + var p = this.getParent(); + if(p){ + p._moveChildToFront(this); + this._moveToFront(); // execute renderer-specific action + } + return this; // self + }, + moveToBack: function(){ + // summary: moves a shape to back of its parent's list of shapes + var p = this.getParent(); + if(p){ + p._moveChildToBack(this); + this._moveToBack(); // execute renderer-specific action + } + return this; + }, + _moveToFront: function(){ + // summary: renderer-specific hook, see dojox.gfx.shape.Shape.moveToFront() + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + }, + _moveToBack: function(){ + // summary: renderer-specific hook, see dojox.gfx.shape.Shape.moveToFront() + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + }, + + // apply left & right transformation + + applyRightTransform: function(matrix){ + // summary: multiplies the existing matrix with an argument on right side + // (this.matrix * matrix) + // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object + // (see an argument of dojox.gfx.Matrix2D + // constructor for a list of acceptable arguments) + return matrix ? this.setTransform([this.matrix, matrix]) : this; // self + }, + applyLeftTransform: function(matrix){ + // summary: multiplies the existing matrix with an argument on left side + // (matrix * this.matrix) + // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object + // (see an argument of dojox.gfx.Matrix2D + // constructor for a list of acceptable arguments) + return matrix ? this.setTransform([matrix, this.matrix]) : this; // self + }, + applyTransform: function(matrix){ + // summary: a shortcut for dojox.gfx.Shape.applyRightTransform + // matrix: dojox.gfx.Matrix2D: a matrix or a matrix-like object + // (see an argument of dojox.gfx.Matrix2D + // constructor for a list of acceptable arguments) + return matrix ? this.setTransform([this.matrix, matrix]) : this; // self + }, + + // virtual group methods + + removeShape: function(silently){ + // summary: removes the shape from its parent's list of shapes + // silently: Boolean?: if true, do not redraw a picture yet + if(this.parent){ + this.parent.remove(this, silently); + } + return this; // self + }, + _setParent: function(parent, matrix){ + // summary: sets a parent + // parent: Object: a parent or null + // (see dojox.gfx.Surface, + // dojox.gfx.shape.VirtualGroup, + // or dojox.gfx.Group) + // matrix: dojox.gfx.Matrix2D: + // a 2D matrix or a matrix-like object + this.parent = parent; + return this._updateParentMatrix(matrix); // self + }, + _updateParentMatrix: function(matrix){ + // summary: updates the parent matrix with new matrix + // matrix: dojox.gfx.Matrix2D: + // a 2D matrix or a matrix-like object + this.parentMatrix = matrix ? dojox.gfx.matrix.clone(matrix) : null; + return this._applyTransform(); // self + }, + _getRealMatrix: function(){ + // summary: returns the cumulative ("real") transformation matrix + // by combining the shape's matrix with its parent's matrix + var m = this.matrix; + var p = this.parent; + while(p){ + if(p.matrix){ + m = dojox.gfx.matrix.multiply(p.matrix, m); + } + p = p.parent; + } + return m; // dojox.gfx.Matrix2D + } +}); + +dojox.gfx.shape._eventsProcessing = { + connect: function(name, object, method){ + // summary: connects a handler to an event on this shape + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + + return arguments.length > 2 ? // Object + dojo.connect(this.getEventSource(), name, object, method) : + dojo.connect(this.getEventSource(), name, object); + }, + disconnect: function(token){ + // summary: connects a handler by token from an event on this shape + + // COULD BE RE-IMPLEMENTED BY THE RENDERER! + + dojo.disconnect(token); + } +}; + +dojo.extend(dojox.gfx.Shape, dojox.gfx.shape._eventsProcessing); + +dojox.gfx.shape.Container = { + // summary: a container of shapes, which can be used + // as a foundation for renderer-specific groups, or as a way + // to logically group shapes (e.g, to propagate matricies) + + _init: function() { + // children: Array: a list of children + this.children = []; + }, + + // group management + + add: function(shape){ + // summary: adds a shape to the list + // shape: dojox.gfx.Shape: a shape + var oldParent = shape.getParent(); + if(oldParent){ + oldParent.remove(shape, true); + } + this.children.push(shape); + return shape._setParent(this, this._getRealMatrix()); // self + }, + remove: function(shape, silently){ + // summary: removes a shape from the list + // silently: Boolean?: if true, do not redraw a picture yet + for(var i = 0; i < this.children.length; ++i){ + if(this.children[i] == shape){ + if(silently){ + // skip for now + }else{ + shape._setParent(null, null); + } + this.children.splice(i, 1); + break; + } + } + return this; // self + }, + clear: function(){ + // summary: removes all shapes from a group/surface + this.children = []; + return this; // self + }, + + // moving child nodes + + _moveChildToFront: function(shape){ + // summary: moves a shape to front of the list of shapes + for(var i = 0; i < this.children.length; ++i){ + if(this.children[i] == shape){ + this.children.splice(i, 1); + this.children.push(shape); + break; + } + } + return this; // self + }, + _moveChildToBack: function(shape){ + // summary: moves a shape to back of the list of shapes + for(var i = 0; i < this.children.length; ++i){ + if(this.children[i] == shape){ + this.children.splice(i, 1); + this.children.unshift(shape); + break; + } + } + return this; // self + } +}; + +dojo.declare("dojox.gfx.shape.Surface", null, { + // summary: a surface object to be used for drawings + constructor: function(){ + // underlying node + this.rawNode = null; + }, + getEventSource: function(){ + // summary: returns a node, which can be used to attach event listeners + return this.rawNode; // Node + }, + _getRealMatrix: function(){ + // summary: always returns the identity matrix + return null; // dojox.gfx.Matrix2D + } +}); + +dojo.extend(dojox.gfx.shape.Surface, dojox.gfx.shape._eventsProcessing); + +dojo.declare("dojox.gfx.Point", null, { + // summary: a hypothetical 2D point to be used for drawings - {x, y} + // description: This object is defined for documentation purposes. + // You should use the naked object instead: {x: 1, y: 2}. +}); + +dojo.declare("dojox.gfx.Rectangle", null, { + // summary: a hypothetical rectangle - {x, y, width, height} + // description: This object is defined for documentation purposes. + // You should use the naked object instead: {x: 1, y: 2, width: 100, height: 200}. +}); + +dojo.declare("dojox.gfx.shape.Rect", dojox.gfx.Shape, { + // summary: a generic rectangle + constructor: function(rawNode) { + // rawNode: Node: a DOM Node + this.shape = dojo.clone(dojox.gfx.defaultRect); + this.rawNode = rawNode; + }, + getBoundingBox: function(){ + // summary: returns the bounding box (its shape in this case) + return this.shape; // dojox.gfx.Rectangle + } +}); + +dojo.declare("dojox.gfx.shape.Ellipse", dojox.gfx.Shape, { + // summary: a generic ellipse + constructor: function(rawNode) { + // rawNode: Node: a DOM Node + this.shape = dojo.clone(dojox.gfx.defaultEllipse); + this.rawNode = rawNode; + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox){ + var shape = this.shape; + this.bbox = {x: shape.cx - shape.rx, y: shape.cy - shape.ry, + width: 2 * shape.rx, height: 2 * shape.ry}; + } + return this.bbox; // dojox.gfx.Rectangle + } +}); + +dojo.declare("dojox.gfx.shape.Circle", dojox.gfx.Shape, { + // summary: a generic circle + // (this is a helper object, which is defined for convenience) + constructor: function(rawNode) { + // rawNode: Node: a DOM Node + this.shape = dojo.clone(dojox.gfx.defaultCircle); + this.rawNode = rawNode; + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox){ + var shape = this.shape; + this.bbox = {x: shape.cx - shape.r, y: shape.cy - shape.r, + width: 2 * shape.r, height: 2 * shape.r}; + } + return this.bbox; // dojox.gfx.Rectangle + } +}); + +dojo.declare("dojox.gfx.shape.Line", dojox.gfx.Shape, { + // summary: a generic line + // (this is a helper object, which is defined for convenience) + constructor: function(rawNode) { + // rawNode: Node: a DOM Node + this.shape = dojo.clone(dojox.gfx.defaultLine); + this.rawNode = rawNode; + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox){ + var shape = this.shape; + this.bbox = { + x: Math.min(shape.x1, shape.x2), + y: Math.min(shape.y1, shape.y2), + width: Math.abs(shape.x2 - shape.x1), + height: Math.abs(shape.y2 - shape.y1) + }; + } + return this.bbox; // dojox.gfx.Rectangle + } +}); + +dojo.declare("dojox.gfx.shape.Polyline", dojox.gfx.Shape, { + // summary: a generic polyline/polygon + // (this is a helper object, which is defined for convenience) + constructor: function(rawNode) { + // rawNode: Node: a DOM Node + this.shape = dojo.clone(dojox.gfx.defaultPolyline); + this.rawNode = rawNode; + }, + setShape: function(points, closed){ + // summary: sets a polyline/polygon shape object + // points: Object: a polyline/polygon shape object + // closed: Boolean: close the polyline to make a polygon + if(points && points instanceof Array){ + // points: Array: an array of points + dojox.gfx.Shape.prototype.setShape.call(this, {points: points}); + if(closed && this.shape.points.length){ + this.shape.points.push(this.shape.points[0]); + } + }else{ + dojox.gfx.Shape.prototype.setShape.call(this, points); + } + return this; // self + }, + getBoundingBox: function(){ + // summary: returns the bounding box + if(!this.bbox && this.shape.points.length){ + var p = this.shape.points; + var l = p.length; + var t = p[0]; + var bbox = {l: t.x, t: t.y, r: t.x, b: t.y}; + for(var i = 1; i < l; ++i){ + t = p[i]; + if(bbox.l > t.x) bbox.l = t.x; + if(bbox.r < t.x) bbox.r = t.x; + if(bbox.t > t.y) bbox.t = t.y; + if(bbox.b < t.y) bbox.b = t.y; + } + this.bbox = { + x: bbox.l, + y: bbox.t, + width: bbox.r - bbox.l, + height: bbox.b - bbox.t + }; + } + return this.bbox; // dojox.gfx.Rectangle + } +}); + +dojo.declare("dojox.gfx.shape.Image", dojox.gfx.Shape, { + // summary: a generic image + // (this is a helper object, which is defined for convenience) + constructor: function(rawNode) { + // rawNode: Node: a DOM Node + this.shape = dojo.clone(dojox.gfx.defaultImage); + this.rawNode = rawNode; + }, + getBoundingBox: function(){ + // summary: returns the bounding box (its shape in this case) + return this.shape; // dojox.gfx.Rectangle + }, + setStroke: function(){ + // summary: ignore setting a stroke style + return this; // self + }, + setFill: function(){ + // summary: ignore setting a fill style + return this; // self + } +}); + +dojo.declare("dojox.gfx.shape.Text", dojox.gfx.Shape, { + // summary: a generic text + constructor: function(rawNode) { + // rawNode: Node: a DOM Node + this.fontStyle = null; + this.shape = dojo.clone(dojox.gfx.defaultText); + this.rawNode = rawNode; + }, + getFont: function(){ + // summary: returns the current font object or null + return this.fontStyle; // Object + }, + setFont: function(newFont){ + // summary: sets a font for text + // newFont: Object: a font object (see dojox.gfx.defaultFont) or a font string + this.fontStyle = typeof newFont == "string" ? dojox.gfx.splitFontString(newFont) : + dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont); + this._setFont(); + return this; // self + } +}); + +dojox.gfx.shape.Creator = { + // summary: shape creators + createShape: function(shape){ + // summary: creates a shape object based on its type; it is meant to be used + // by group-like objects + // shape: Object: a shape descriptor object + switch(shape.type){ + case dojox.gfx.defaultPath.type: return this.createPath(shape); + case dojox.gfx.defaultRect.type: return this.createRect(shape); + case dojox.gfx.defaultCircle.type: return this.createCircle(shape); + case dojox.gfx.defaultEllipse.type: return this.createEllipse(shape); + case dojox.gfx.defaultLine.type: return this.createLine(shape); + case dojox.gfx.defaultPolyline.type: return this.createPolyline(shape); + case dojox.gfx.defaultImage.type: return this.createImage(shape); + case dojox.gfx.defaultText.type: return this.createText(shape); + case dojox.gfx.defaultTextPath.type: return this.createTextPath(shape); + } + return null; + }, + createGroup: function(){ + // summary: creates an SVG group shape + return this.createObject(dojox.gfx.Group); // dojox.gfx.Group + }, + createRect: function(rect){ + // summary: creates an SVG rectangle shape + // rect: Object: a path object (see dojox.gfx.defaultRect) + return this.createObject(dojox.gfx.Rect, rect); // dojox.gfx.Rect + }, + createEllipse: function(ellipse){ + // summary: creates an SVG ellipse shape + // ellipse: Object: an ellipse object (see dojox.gfx.defaultEllipse) + return this.createObject(dojox.gfx.Ellipse, ellipse); // dojox.gfx.Ellipse + }, + createCircle: function(circle){ + // summary: creates an SVG circle shape + // circle: Object: a circle object (see dojox.gfx.defaultCircle) + return this.createObject(dojox.gfx.Circle, circle); // dojox.gfx.Circle + }, + createLine: function(line){ + // summary: creates an SVG line shape + // line: Object: a line object (see dojox.gfx.defaultLine) + return this.createObject(dojox.gfx.Line, line); // dojox.gfx.Line + }, + createPolyline: function(points){ + // summary: creates an SVG polyline/polygon shape + // points: Object: a points object (see dojox.gfx.defaultPolyline) + // or an Array of points + return this.createObject(dojox.gfx.Polyline, points); // dojox.gfx.Polyline + }, + createImage: function(image){ + // summary: creates an SVG image shape + // image: Object: an image object (see dojox.gfx.defaultImage) + return this.createObject(dojox.gfx.Image, image); // dojox.gfx.Image + }, + createText: function(text){ + // summary: creates an SVG text shape + // text: Object: a text object (see dojox.gfx.defaultText) + return this.createObject(dojox.gfx.Text, text); // dojox.gfx.Text + }, + createPath: function(path){ + // summary: creates an SVG path shape + // path: Object: a path object (see dojox.gfx.defaultPath) + return this.createObject(dojox.gfx.Path, path); // dojox.gfx.Path + }, + createTextPath: function(text){ + // summary: creates an SVG text shape + // text: Object: a textpath object (see dojox.gfx.defaultTextPath) + return this.createObject(dojox.gfx.TextPath, {}).setText(text); // dojox.gfx.TextPath + }, + createObject: function(shapeType, rawShape){ + // summary: creates an instance of the passed shapeType class + // shapeType: Function: a class constructor to create an instance of + // rawShape: Object: properties to be passed in to the classes "setShape" method + + // SHOULD BE RE-IMPLEMENTED BY THE RENDERER! + + return null; // dojox.gfx.Shape + } +}; + +} diff --git a/includes/js/dojox/gfx/silverlight.js b/includes/js/dojox/gfx/silverlight.js new file mode 100644 index 0000000..7a4becc --- /dev/null +++ b/includes/js/dojox/gfx/silverlight.js @@ -0,0 +1,693 @@ +if(!dojo._hasResource["dojox.gfx.silverlight"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.silverlight"] = true; +dojo.provide("dojox.gfx.silverlight"); + +dojo.require("dojox.gfx._base"); +dojo.require("dojox.gfx.shape"); +dojo.require("dojox.gfx.path"); + +dojo.experimental("dojox.gfx.silverlight"); + +dojox.gfx.silverlight.dasharray = { + solid: "none", + shortdash: [4, 1], + shortdot: [1, 1], + shortdashdot: [4, 1, 1, 1], + shortdashdotdot: [4, 1, 1, 1, 1, 1], + dot: [1, 3], + dash: [4, 3], + longdash: [8, 3], + dashdot: [4, 3, 1, 3], + longdashdot: [8, 3, 1, 3], + longdashdotdot: [8, 3, 1, 3, 1, 3] +}; + +dojox.gfx.silverlight.fontweight = { + normal: 400, + bold: 700 +}; + +dojox.gfx.silverlight.caps = {butt: "Flat", round: "Round", square: "Square"}; +dojox.gfx.silverlight.joins = {bevel: "Bevel", round: "Round"}; + +dojox.gfx.silverlight.fonts = { + serif: "Times New Roman", + times: "Times New Roman", + "sans-serif": "Arial", + helvetica: "Arial", + monotone: "Courier New", + courier: "Courier New" +}; + +dojox.gfx.silverlight.hexColor = function(/*String|Array|dojo.Color*/ color){ + // summary: converts a color object to a Silverlight hex color string (#aarrggbb) + var c = dojox.gfx.normalizeColor(color), + t = c.toHex(), a = Math.round(c.a * 255); + a = (a < 0 ? 0 : a > 255 ? 255 : a).toString(16); + return "#" + (a.length < 2 ? "0" + a : a) + t.slice(1); // String +}; + +dojo.extend(dojox.gfx.Shape, { + // summary: Silverlight-specific implementation of dojox.gfx.Shape methods + + setFill: function(fill){ + // summary: sets a fill object (Silverlight) + // fill: Object: a fill object + // (see dojox.gfx.defaultLinearGradient, + // dojox.gfx.defaultRadialGradient, + // dojox.gfx.defaultPattern, + // or dojo.Color) + + var p = this.rawNode.getHost().content, r = this.rawNode, f; + if(!fill){ + // don't fill + this.fillStyle = null; + this._setFillAttr(null); + return this; // self + } + if(typeof(fill) == "object" && "type" in fill){ + // gradient + switch(fill.type){ + case "linear": + this.fillStyle = f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill); + var lgb = p.createFromXaml(""); + lgb.mappingMode = "Absolute"; + lgb.startPoint = f.x1 + "," + f.y1; + lgb.endPoint = f.x2 + "," + f.y2; + dojo.forEach(f.colors, function(c){ + var t = p.createFromXaml(""); + t.offset = c.offset; + t.color = dojox.gfx.silverlight.hexColor(c.color); + lgb.gradientStops.add(t); + }); + this._setFillAttr(lgb); + break; + case "radial": + this.fillStyle = f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill); + var rgb = p.createFromXaml(""), w = r.width, h = r.height, + l = this.rawNode["Canvas.Left"], t = this.rawNode["Canvas.Top"]; + rgb.center = (f.cx - l) / w + "," + (f.cy - t) / h; + rgb.radiusX = f.r / w; + rgb.radiusY = f.r / h; + dojo.forEach(f.colors, function(c){ + var t = p.createFromXaml(""); + t.offset = c.offset; + t.color = dojox.gfx.silverlight.hexColor(c.color); + rgb.gradientStops.add(t); + }); + this._setFillAttr(rgb); + break; + case "pattern": + // don't fill: Silverlight doesn't define TileBrush for some reason + this.fillStyle = null; + this._setFillAttr(null); + break; + } + return this; // self + } + // color object + this.fillStyle = f = dojox.gfx.normalizeColor(fill); + var scb = p.createFromXaml(""); + scb.color = f.toHex(); + scb.opacity = f.a; + this._setFillAttr(scb); + return this; // self + }, + _setFillAttr: function(f){ + this.rawNode.fill = f; + }, + + setStroke: function(stroke){ + // summary: sets a stroke object (Silverlight) + // stroke: Object: a stroke object + // (see dojox.gfx.defaultStroke) + + var p = this.rawNode.getHost().content, r = this.rawNode; + if(!stroke){ + // don't stroke + this.strokeStyle = null; + r.stroke = null; + return this; + } + // normalize the stroke + if(typeof stroke == "string"){ + stroke = {color: stroke}; + } + var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke); + s.color = dojox.gfx.normalizeColor(s.color); + // generate attributes + if(s){ + var scb = p.createFromXaml(""); + scb.color = s.color.toHex(); + scb.opacity = s.color.a; + r.stroke = scb; + r.strokeThickness = s.width; + r.strokeStartLineCap = r.strokeEndLineCap = r.strokeDashCap = + dojox.gfx.silverlight.caps[s.cap]; + if(typeof s.join == "number"){ + r.strokeLineJoin = "Miter"; + r.strokeMiterLimit = s.join; + }else{ + r.strokeLineJoin = dojox.gfx.silverlight.joins[s.join]; + } + var da = s.style.toLowerCase(); + if(da in dojox.gfx.silverlight.dasharray){ da = dojox.gfx.silverlight.dasharray[da]; } + if(da instanceof Array){ + da = dojo.clone(da); + /* + for(var i = 0; i < da.length; ++i){ + da[i] *= s.width; + } + */ + if(s.cap != "butt"){ + for(var i = 0; i < da.length; i += 2){ + //da[i] -= s.width; + --da[i] + if(da[i] < 1){ da[i] = 1; } + } + for(var i = 1; i < da.length; i += 2){ + //da[i] += s.width; + ++da[i]; + } + } + r.strokeDashArray = da.join(","); + }else{ + r.strokeDashArray = null; + } + } + return this; // self + }, + + _getParentSurface: function(){ + var surface = this.parent; + for(; surface && !(surface instanceof dojox.gfx.Surface); surface = surface.parent); + return surface; + }, + + _applyTransform: function() { + var tm = this.matrix, r = this.rawNode; + if(tm){ + var p = this.rawNode.getHost().content, + m = p.createFromXaml(""), + mm = p.createFromXaml(""); + mm.m11 = tm.xx; + mm.m21 = tm.xy; + mm.m12 = tm.yx; + mm.m22 = tm.yy; + mm.offsetX = tm.dx; + mm.offsetY = tm.dy; + m.matrix = mm; + r.renderTransform = m; + }else{ + r.renderTransform = null; + } + return this; + }, + + setRawNode: function(rawNode){ + // summary: + // assigns and clears the underlying node that will represent this + // shape. Once set, transforms, gradients, etc, can be applied. + // (no fill & stroke by default) + rawNode.fill = null; + rawNode.stroke = null; + this.rawNode = rawNode; + }, + + // move family + + _moveToFront: function(){ + // summary: moves a shape to front of its parent's list of shapes (Silverlight) + var c = this.parent.rawNode.children, r = this.rawNode; + c.remove(r); + c.add(r); + return this; // self + }, + _moveToBack: function(){ + // summary: moves a shape to back of its parent's list of shapes (Silverlight) + var c = this.parent.rawNode.children, r = this.rawNode; + c.remove(r); + c.insert(0, r); + return this; // self + } +}); + +dojo.declare("dojox.gfx.Group", dojox.gfx.Shape, { + // summary: a group shape (Silverlight), which can be used + // to logically group shapes (e.g, to propagate matricies) + constructor: function(){ + dojox.gfx.silverlight.Container._init.call(this); + }, + setRawNode: function(rawNode){ + // summary: sets a raw Silverlight node to be used by this shape + // rawNode: Node: an Silverlight node + this.rawNode = rawNode; + } +}); +dojox.gfx.Group.nodeType = "Canvas"; + +dojo.declare("dojox.gfx.Rect", dojox.gfx.shape.Rect, { + // summary: a rectangle shape (Silverlight) + setShape: function(newShape){ + // summary: sets a rectangle shape object (Silverlight) + // newShape: Object: a rectangle shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var r = this.rawNode, n = this.shape; + r["Canvas.Left"] = n.x; + r["Canvas.Top"] = n.y; + r.width = n.width; + r.height = n.height; + r.radiusX = r.radiusY = n.r; + return this; // self + } +}); +dojox.gfx.Rect.nodeType = "Rectangle"; + +dojo.declare("dojox.gfx.Ellipse", dojox.gfx.shape.Ellipse, { + // summary: an ellipse shape (Silverlight) + setShape: function(newShape){ + // summary: sets an ellipse shape object (Silverlight) + // newShape: Object: an ellipse shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var r = this.rawNode, n = this.shape; + r["Canvas.Left"] = n.cx - n.rx; + r["Canvas.Top"] = n.cy - n.ry; + r.width = 2 * n.rx; + r.height = 2 * n.ry; + return this; // self + } +}); +dojox.gfx.Ellipse.nodeType = "Ellipse"; + +dojo.declare("dojox.gfx.Circle", dojox.gfx.shape.Circle, { + // summary: a circle shape (Silverlight) + setShape: function(newShape){ + // summary: sets a circle shape object (Silverlight) + // newShape: Object: a circle shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var r = this.rawNode, n = this.shape; + r["Canvas.Left"] = n.cx - n.r; + r["Canvas.Top"] = n.cy - n.r; + r.width = r.height = 2 * n.r; + return this; // self + } +}); +dojox.gfx.Circle.nodeType = "Ellipse"; + +dojo.declare("dojox.gfx.Line", dojox.gfx.shape.Line, { + // summary: a line shape (Silverlight) + setShape: function(newShape){ + // summary: sets a line shape object (Silverlight) + // newShape: Object: a line shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var r = this.rawNode, n = this.shape; + r.x1 = n.x1; r.y1 = n.y1; r.x2 = n.x2; r.y2 = n.y2; + return this; // self + } +}); +dojox.gfx.Line.nodeType = "Line"; + +dojo.declare("dojox.gfx.Polyline", dojox.gfx.shape.Polyline, { + // summary: a polyline/polygon shape (Silverlight) + setShape: function(points, closed){ + // summary: sets a polyline/polygon shape object (Silverlight) + // points: Object: a polyline/polygon shape object + if(points && points instanceof Array){ + // branch + // points: Array: an array of points + this.shape = dojox.gfx.makeParameters(this.shape, {points: points}); + if(closed && this.shape.points.length){ + this.shape.points.push(this.shape.points[0]); + } + }else{ + this.shape = dojox.gfx.makeParameters(this.shape, points); + } + this.box = null; + var p = this.shape.points, rp = []; + for(var i = 0; i < p.length; ++i){ + if(typeof p[i] == "number"){ + rp.push(p[i], p[++i]); + }else{ + rp.push(p[i].x, p[i].y); + } + } + this.rawNode.points = rp.join(","); + return this; // self + } +}); +dojox.gfx.Polyline.nodeType = "Polyline"; + +dojo.declare("dojox.gfx.Image", dojox.gfx.shape.Image, { + // summary: an image (Silverlight) + setShape: function(newShape){ + // summary: sets an image shape object (Silverlight) + // newShape: Object: an image shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var r = this.rawNode, n = this.shape; + r["Canvas.Left"] = n.x; + r["Canvas.Top"] = n.y; + r.width = n.width; + r.height = n.height; + r.source = n.src; + return this; // self + }, + setRawNode: function(rawNode){ + // summary: + // assigns and clears the underlying node that will represent this + // shape. Once set, transforms, gradients, etc, can be applied. + // (no fill & stroke by default) + this.rawNode = rawNode; + } +}); +dojox.gfx.Image.nodeType = "Image"; + +dojo.declare("dojox.gfx.Text", dojox.gfx.shape.Text, { + // summary: an anchored text (Silverlight) + setShape: function(newShape){ + // summary: sets a text shape object (Silverlight) + // newShape: Object: a text shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var r = this.rawNode, s = this.shape; + r.text = s.text; + r.textDecorations = s.decoration == "underline" ? "Underline" : "None"; + r["Canvas.Left"] = -10000; + r["Canvas.Top"] = -10000; + window.setTimeout(dojo.hitch(this, "_delayAlignment"), 0); + return this; // self + }, + _delayAlignment: function(){ + // handle alignment + var r = this.rawNode, s = this.shape, + w = r.actualWidth, h = r.actualHeight, x = s.x, y = s.y - h * 0.75; + switch(s.align){ + case "middle": + x -= w / 2; + break; + case "end": + x -= w; + break; + } + var a = this.matrix ? dojox.gfx.matrix.multiplyPoint(this.matrix, x, y) : {x: x, y: y}; + r["Canvas.Left"] = a.x; + r["Canvas.Top"] = a.y; + }, + setStroke: function(){ + // summary: ignore setting a stroke style + return this; // self + }, + _setFillAttr: function(f){ + this.rawNode.foreground = f; + }, + setRawNode: function(rawNode){ + // summary: + // assigns and clears the underlying node that will represent this + // shape. Once set, transforms, gradients, etc, can be applied. + // (no fill & stroke by default) + this.rawNode = rawNode; + }, + _applyTransform: function() { + var tm = this.matrix, r = this.rawNode; + if(tm){ + // the next line is pure magic :-( + tm = dojox.gfx.matrix.normalize([1/100, tm, 100]); + var p = this.rawNode.getHost().content, + m = p.createFromXaml(""), + mm = p.createFromXaml(""); + mm.m11 = tm.xx; + mm.m21 = tm.xy; + mm.m12 = tm.yx; + mm.m22 = tm.yy; + mm.offsetX = tm.dx; + mm.offsetY = tm.dy; + m.matrix = mm; + r.renderTransform = m; + }else{ + r.renderTransform = null; + } + return this; + }, + getTextWidth: function(){ + // summary: get the text width in pixels + return this.rawNode.actualWidth; + } +}); +dojox.gfx.Text.nodeType = "TextBlock"; + +dojo.declare("dojox.gfx.Path", dojox.gfx.path.Path, { + // summary: a path shape (Silverlight) + _updateWithSegment: function(segment){ + // summary: updates the bounding box of path with new segment + // segment: Object: a segment + dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments); + var p = this.shape.path; + if(typeof(p) == "string"){ + this.rawNode.data = p ? p : null; + } + }, + setShape: function(newShape){ + // summary: forms a path using a shape (Silverlight) + // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath) + dojox.gfx.Path.superclass.setShape.apply(this, arguments); + var p = this.shape.path; + this.rawNode.data = p ? p : null; + return this; // self + } +}); +dojox.gfx.Path.nodeType = "Path"; + +dojo.declare("dojox.gfx.TextPath", dojox.gfx.path.TextPath, { + // summary: a textpath shape (Silverlight) + _updateWithSegment: function(segment){ + // summary: updates the bounding box of path with new segment + // segment: Object: a segment + }, + setShape: function(newShape){ + // summary: forms a path using a shape (Silverlight) + // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath) + }, + _setText: function(){ + } +}); +dojox.gfx.TextPath.nodeType = "text"; + +dojo.declare("dojox.gfx.Surface", dojox.gfx.shape.Surface, { + // summary: a surface object to be used for drawings (Silverlight) + constructor: function(){ + dojox.gfx.silverlight.Container._init.call(this); + }, + setDimensions: function(width, height){ + // summary: sets the width and height of the rawNode + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + this.width = dojox.gfx.normalizedLength(width); // in pixels + this.height = dojox.gfx.normalizedLength(height); // in pixels + var p = this.rawNode && this.rawNode.getHost(); + if(p){ + p.width = width; + p.height = height; + } + return this; // self + }, + getDimensions: function(){ + // summary: returns an object with properties "width" and "height" + var p = this.rawNode && this.rawNode.getHost(); + var t = p ? {width: p.content.actualWidth, height: p.content.actualHeight} : null; + if(t.width <= 0){ t.width = this.width; } + if(t.height <= 0){ t.height = this.height; } + return t; // Object + } +}); + +dojox.gfx.silverlight.surfaces = {}; + +dojox.gfx.createSurface = function(parentNode, width, height){ + // summary: creates a surface (Silverlight) + // parentNode: Node: a parent node + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + + var s = new dojox.gfx.Surface(); + parentNode = dojo.byId(parentNode); + // create an empty canvas + var t = parentNode.ownerDocument.createElement("script"); + t.type = "text/xaml"; + t.id = dojox.gfx._base._getUniqueId(); + t.text = ""; + document.body.appendChild(t); + // create a plugin + var pluginName = dojox.gfx._base._getUniqueId(); + Silverlight.createObject( + "#" + t.id, // none + parentNode, + pluginName, + { // Plugin properties. + width: String(width), // Width of rectangular region of plugin in pixels. + height: String(height), // Height of rectangular region of plugin in pixels. + inplaceInstallPrompt: "false", // Determines whether to display in-place install prompt if invalid version detected. + //background: "white", // Background color of plugin. + //isWindowless: "false", // Determines whether to display plugin in Windowless mode. + background: "transparent", // Background color of plugin. + isWindowless: "true", // Determines whether to display plugin in Windowless mode. + framerate: "24", // MaxFrameRate property value. + version: "1.0" // Silverlight version. + }, + {}, + null, + null + ); + s.rawNode = dojo.byId(pluginName).content.root; + // register the plugin with its parent node + dojox.gfx.silverlight.surfaces[s.rawNode.name] = parentNode; + s.width = dojox.gfx.normalizedLength(width); // in pixels + s.height = dojox.gfx.normalizedLength(height); // in pixels + return s; // dojox.gfx.Surface +}; + +// Extenders + +dojox.gfx.silverlight.Font = { + _setFont: function(){ + // summary: sets a font object (Silverlight) + var f = this.fontStyle, r = this.rawNode, + fw = dojox.gfx.silverlight.fontweight, + fo = dojox.gfx.silverlight.fonts, t = f.family.toLowerCase(); + r.fontStyle = f.style == "italic" ? "Italic" : "Normal"; + r.fontWeight = f.weight in fw ? fw[f.weight] : f.weight; + r.fontSize = dojox.gfx.normalizedLength(f.size); + r.fontFamily = t in fo ? fo[t] : f.family; + } +}; + +dojox.gfx.silverlight.Container = { + _init: function(){ + dojox.gfx.shape.Container._init.call(this); + }, + add: function(shape){ + // summary: adds a shape to a group/surface + // shape: dojox.gfx.Shape: an VML shape object + if(this != shape.getParent()){ + //dojox.gfx.Group.superclass.add.apply(this, arguments); + //this.inherited(arguments); + dojox.gfx.shape.Container.add.apply(this, arguments); + this.rawNode.children.add(shape.rawNode); + } + return this; // self + }, + remove: function(shape, silently){ + // summary: remove a shape from a group/surface + // shape: dojox.gfx.Shape: an VML shape object + // silently: Boolean?: if true, regenerate a picture + if(this == shape.getParent()){ + var parent = shape.rawNode.getParent(); + if(parent){ + parent.children.remove(shape.rawNode); + } + //dojox.gfx.Group.superclass.remove.apply(this, arguments); + //this.inherited(arguments); + dojox.gfx.shape.Container.remove.apply(this, arguments); + } + return this; // self + }, + clear: function(){ + // summary: removes all shapes from a group/surface + this.rawNode.children.clear(); + //return this.inherited(arguments); // self + return dojox.gfx.shape.Container.clear.apply(this, arguments); + }, + _moveChildToFront: dojox.gfx.shape.Container._moveChildToFront, + _moveChildToBack: dojox.gfx.shape.Container._moveChildToBack +}; + +dojo.mixin(dojox.gfx.shape.Creator, { + createObject: function(shapeType, rawShape){ + // summary: creates an instance of the passed shapeType class + // shapeType: Function: a class constructor to create an instance of + // rawShape: Object: properties to be passed in to the classes "setShape" method + if(!this.rawNode){ return null; } + var shape = new shapeType(); + var node = this.rawNode.getHost().content.createFromXaml("<" + shapeType.nodeType + "/>"); + shape.setRawNode(node); + shape.setShape(rawShape); + this.add(shape); + return shape; // dojox.gfx.Shape + } +}); + +dojo.extend(dojox.gfx.Text, dojox.gfx.silverlight.Font); +//dojo.extend(dojox.gfx.TextPath, dojox.gfx.silverlight.Font); + +dojo.extend(dojox.gfx.Group, dojox.gfx.silverlight.Container); +dojo.extend(dojox.gfx.Group, dojox.gfx.shape.Creator); + +dojo.extend(dojox.gfx.Surface, dojox.gfx.silverlight.Container); +dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator); + +(function(){ + var surfaces = dojox.gfx.silverlight.surfaces; + var mouseFix = function(s, a){ + var ev = {target: s, currentTarget: s, + preventDefault: function(){}, stopPropagation: function(){}}; + if(a){ + ev.ctrlKey = a.ctrl; + ev.shiftKey = a.shift; + var p = a.getPosition(null); + ev.x = ev.offsetX = ev.layerX = p.x; + ev.y = ev.offsetY = ev.layerY = p.y; + // calculate clientX and clientY + var parent = surfaces[s.getHost().content.root.name]; + var t = dojo._abs(parent); + ev.clientX = t.x + p.x; + ev.clientY = t.y + p.y; + } + return ev; + }; + var keyFix = function(s, a){ + var ev = { + keyCode: a.platformKeyCode, + ctrlKey: a.ctrl, + shiftKey: a.shift + }; + return ev; + }; + var eventNames = { + onclick: {name: "MouseLeftButtonUp", fix: mouseFix}, + onmouseenter: {name: "MouseEnter", fix: mouseFix}, + onmouseleave: {name: "MouseLeave", fix: mouseFix}, + onmousedown: {name: "MouseLeftButtonDown", fix: mouseFix}, + onmouseup: {name: "MouseLeftButtonUp", fix: mouseFix}, + onmousemove: {name: "MouseMove", fix: mouseFix}, + onkeydown: {name: "KeyDown", fix: keyFix}, + onkeyup: {name: "KeyUp", fix: keyFix} + }; + var eventsProcessing = { + connect: function(name, object, method){ + var token, n = name in eventNames ? eventNames[name] : + {name: name, fix: function(){ return {}; }}; + if(arguments.length > 2){ + token = this.getEventSource().addEventListener(n.name, + function(s, a){ dojo.hitch(object, method)(n.fix(s, a)); }); + }else{ + token = this.getEventSource().addEventListener(n.name, + function(s, a){ object(n.fix(s, a)); }); + } + return {name: n.name, token: token}; + }, + disconnect: function(token){ + this.getEventSource().removeEventListener(token.name, token.token); + } + }; + dojo.extend(dojox.gfx.Shape, eventsProcessing); + dojo.extend(dojox.gfx.Surface, eventsProcessing); + dojox.gfx.equalSources = function(a, b){ + return a && b && a.equals(b); + } + +})(); + +} diff --git a/includes/js/dojox/gfx/silverlight_attach.js b/includes/js/dojox/gfx/silverlight_attach.js new file mode 100644 index 0000000..1f5cd90 --- /dev/null +++ b/includes/js/dojox/gfx/silverlight_attach.js @@ -0,0 +1,87 @@ +dojo.require("dojox.gfx.silverlight"); + +dojo.experimental("dojox.gfx.silverlight_attach"); + +(function(){ + dojox.gfx.attachNode = function(node){ + // summary: creates a shape from a Node + // node: Node: an Silverlight node + return null; // for now + if(!node) return null; + var s = null; + switch(node.tagName.toLowerCase()){ + case dojox.gfx.Rect.nodeType: + s = new dojox.gfx.Rect(node); + break; + case dojox.gfx.Ellipse.nodeType: + if(node.width == node.height){ + s = new dojox.gfx.Circle(node); + }else{ + s = new dojox.gfx.Ellipse(node); + } + break; + case dojox.gfx.Polyline.nodeType: + s = new dojox.gfx.Polyline(node); + break; + case dojox.gfx.Path.nodeType: + s = new dojox.gfx.Path(node); + break; + case dojox.gfx.Line.nodeType: + s = new dojox.gfx.Line(node); + break; + case dojox.gfx.Image.nodeType: + s = new dojox.gfx.Image(node); + break; + case dojox.gfx.Text.nodeType: + s = new dojox.gfx.Text(node); + attachFont(s); + break; + default: + //console.debug("FATAL ERROR! tagName = " + node.tagName); + return null; + } + attachShape(s); + if(!(s instanceof dojox.gfx.Image)){ + attachFill(s); + attachStroke(s); + } + attachTransform(s); + return s; // dojox.gfx.Shape + }; + + dojox.gfx.attachSurface = function(node){ + // summary: creates a surface from a Node + // node: Node: an Silverlight node + return null; // dojox.gfx.Surface + }; + + var attachFill = function(rawNode){ + // summary: deduces a fill style from a Node. + // rawNode: Node: an Silverlight node + return null; // Object + }; + + var attachStroke = function(rawNode){ + // summary: deduces a stroke style from a Node. + // rawNode: Node: an SVG node + return null; // Object + }; + + var attachTransform = function(rawNode){ + // summary: deduces a transformation matrix from a Node. + // rawNode: Node: an Silverlight node + return null; // dojox.gfx.matrix.Matrix + }; + + var attachFont = function(rawNode){ + // summary: deduces a font style from a Node. + // rawNode: Node: an Silverlight node + return null; // Object + }; + + var attachShape = function(rawNode){ + // summary: builds a shape from a Node. + // rawNode: Node: an Silverlight node + return null; // dojox.gfx.Shape + }; +})(); diff --git a/includes/js/dojox/gfx/svg.js b/includes/js/dojox/gfx/svg.js new file mode 100644 index 0000000..5f6101c --- /dev/null +++ b/includes/js/dojox/gfx/svg.js @@ -0,0 +1,638 @@ +if(!dojo._hasResource["dojox.gfx.svg"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.svg"] = true; +dojo.provide("dojox.gfx.svg"); + +dojo.require("dojox.gfx._base"); +dojo.require("dojox.gfx.shape"); +dojo.require("dojox.gfx.path"); + +dojox.gfx.svg.xmlns = { + xlink: "http://www.w3.org/1999/xlink", + svg: "http://www.w3.org/2000/svg" +}; + +dojox.gfx.svg.getRef = function(name){ + // summary: returns a DOM Node specified by the name argument or null + // name: String: an SVG external reference + if(!name || name == "none") return null; + if(name.match(/^url\(#.+\)$/)){ + return dojo.byId(name.slice(5, -1)); // Node + } + // alternative representation of a reference + if(name.match(/^#dojoUnique\d+$/)){ + // we assume here that a reference was generated by dojox.gfx + return dojo.byId(name.slice(1)); // Node + } + return null; // Node +}; + +dojox.gfx.svg.dasharray = { + solid: "none", + shortdash: [4, 1], + shortdot: [1, 1], + shortdashdot: [4, 1, 1, 1], + shortdashdotdot: [4, 1, 1, 1, 1, 1], + dot: [1, 3], + dash: [4, 3], + longdash: [8, 3], + dashdot: [4, 3, 1, 3], + longdashdot: [8, 3, 1, 3], + longdashdotdot: [8, 3, 1, 3, 1, 3] +}; + +dojo.extend(dojox.gfx.Shape, { + // summary: SVG-specific implementation of dojox.gfx.Shape methods + + setFill: function(fill){ + // summary: sets a fill object (SVG) + // fill: Object: a fill object + // (see dojox.gfx.defaultLinearGradient, + // dojox.gfx.defaultRadialGradient, + // dojox.gfx.defaultPattern, + // or dojo.Color) + + if(!fill){ + // don't fill + this.fillStyle = null; + this.rawNode.setAttribute("fill", "none"); + this.rawNode.setAttribute("fill-opacity", 0); + return this; + } + var f; + // FIXME: slightly magical. We're using the outer scope's "f", but setting it later + var setter = function(x){ + // we assume that we're executing in the scope of the node to mutate + this.setAttribute(x, f[x].toFixed(8)); + }; + if(typeof(fill) == "object" && "type" in fill){ + // gradient + switch(fill.type){ + case "linear": + f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill); + var gradient = this._setFillObject(f, "linearGradient"); + dojo.forEach(["x1", "y1", "x2", "y2"], setter, gradient); + break; + case "radial": + f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill); + var gradient = this._setFillObject(f, "radialGradient"); + dojo.forEach(["cx", "cy", "r"], setter, gradient); + break; + case "pattern": + f = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill); + var pattern = this._setFillObject(f, "pattern"); + dojo.forEach(["x", "y", "width", "height"], setter, pattern); + break; + } + this.fillStyle = f; + return this; + } + // color object + var f = dojox.gfx.normalizeColor(fill); + this.fillStyle = f; + this.rawNode.setAttribute("fill", f.toCss()); + this.rawNode.setAttribute("fill-opacity", f.a); + this.rawNode.setAttribute("fill-rule", "evenodd"); + return this; // self + }, + + setStroke: function(stroke){ + // summary: sets a stroke object (SVG) + // stroke: Object: a stroke object + // (see dojox.gfx.defaultStroke) + + if(!stroke){ + // don't stroke + this.strokeStyle = null; + this.rawNode.setAttribute("stroke", "none"); + this.rawNode.setAttribute("stroke-opacity", 0); + return this; + } + // normalize the stroke + if(typeof stroke == "string"){ + stroke = {color: stroke}; + } + var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke); + s.color = dojox.gfx.normalizeColor(s.color); + // generate attributes + var rn = this.rawNode; + if(s){ + rn.setAttribute("stroke", s.color.toCss()); + rn.setAttribute("stroke-opacity", s.color.a); + rn.setAttribute("stroke-width", s.width); + rn.setAttribute("stroke-linecap", s.cap); + if(typeof s.join == "number"){ + rn.setAttribute("stroke-linejoin", "miter"); + rn.setAttribute("stroke-miterlimit", s.join); + }else{ + rn.setAttribute("stroke-linejoin", s.join); + } + var da = s.style.toLowerCase(); + if(da in dojox.gfx.svg.dasharray){ da = dojox.gfx.svg.dasharray[da]; } + if(da instanceof Array){ + da = dojo.clone(da); + for(var i = 0; i < da.length; ++i){ + da[i] *= s.width; + } + if(s.cap != "butt"){ + for(var i = 0; i < da.length; i += 2){ + da[i] -= s.width; + if(da[i] < 1){ da[i] = 1; } + } + for(var i = 1; i < da.length; i += 2){ + da[i] += s.width; + } + } + da = da.join(","); + } + rn.setAttribute("stroke-dasharray", da); + rn.setAttribute("dojoGfxStrokeStyle", s.style); + } + return this; // self + }, + + _getParentSurface: function(){ + var surface = this.parent; + for(; surface && !(surface instanceof dojox.gfx.Surface); surface = surface.parent); + return surface; + }, + + _setFillObject: function(f, nodeType){ + var svgns = dojox.gfx.svg.xmlns.svg; + this.fillStyle = f; + var surface = this._getParentSurface(), + defs = surface.defNode, + fill = this.rawNode.getAttribute("fill"), + ref = dojox.gfx.svg.getRef(fill); + if(ref){ + fill = ref; + if(fill.tagName.toLowerCase() != nodeType.toLowerCase()){ + var id = fill.id; + fill.parentNode.removeChild(fill); + fill = document.createElementNS(svgns, nodeType); + fill.setAttribute("id", id); + defs.appendChild(fill); + }else{ + while(fill.childNodes.length){ + fill.removeChild(fill.lastChild); + } + } + }else{ + fill = document.createElementNS(svgns, nodeType); + fill.setAttribute("id", dojox.gfx._base._getUniqueId()); + defs.appendChild(fill); + } + if(nodeType == "pattern"){ + if(dojo.isSafari){ + fill.setAttributeNS(null, "patternUnits", "userSpaceOnUse"); + }else{ + fill.setAttribute("patternUnits", "userSpaceOnUse"); + } + var img = document.createElementNS(svgns, "image"); + img.setAttribute("x", 0); + img.setAttribute("y", 0); + img.setAttribute("width", f.width .toFixed(8)); + img.setAttribute("height", f.height.toFixed(8)); + img.setAttributeNS(dojox.gfx.svg.xmlns.xlink, "href", f.src); + fill.appendChild(img); + }else{ + if(dojo.isSafari){ + fill.setAttributeNS(null, "gradientUnits", "userSpaceOnUse"); + }else{ + fill.setAttribute("gradientUnits", "userSpaceOnUse"); + } + for(var i = 0; i < f.colors.length; ++i){ + var c = f.colors[i], t = document.createElementNS(svgns, "stop"), + cc = c.color = dojox.gfx.normalizeColor(c.color); + t.setAttribute("offset", c.offset.toFixed(8)); + t.setAttribute("stop-color", cc.toCss()); + t.setAttribute("stop-opacity", cc.a); + fill.appendChild(t); + } + } + this.rawNode.setAttribute("fill", "url(#" + fill.getAttribute("id") +")"); + this.rawNode.removeAttribute("fill-opacity"); + this.rawNode.setAttribute("fill-rule", "evenodd"); + return fill; + }, + + _applyTransform: function() { + var matrix = this.matrix; + if(matrix){ + var tm = this.matrix; + this.rawNode.setAttribute("transform", "matrix(" + + tm.xx.toFixed(8) + "," + tm.yx.toFixed(8) + "," + + tm.xy.toFixed(8) + "," + tm.yy.toFixed(8) + "," + + tm.dx.toFixed(8) + "," + tm.dy.toFixed(8) + ")"); + }else{ + this.rawNode.removeAttribute("transform"); + } + return this; + }, + + setRawNode: function(rawNode){ + // summary: + // assigns and clears the underlying node that will represent this + // shape. Once set, transforms, gradients, etc, can be applied. + // (no fill & stroke by default) + var r = this.rawNode = rawNode; + r.setAttribute("fill", "none"); + r.setAttribute("fill-opacity", 0); + r.setAttribute("stroke", "none"); + r.setAttribute("stroke-opacity", 0); + r.setAttribute("stroke-width", 1); + r.setAttribute("stroke-linecap", "butt"); + r.setAttribute("stroke-linejoin", "miter"); + r.setAttribute("stroke-miterlimit", 4); + }, + + setShape: function(newShape){ + // summary: sets a shape object (SVG) + // newShape: Object: a shape object + // (see dojox.gfx.defaultPath, + // dojox.gfx.defaultPolyline, + // dojox.gfx.defaultRect, + // dojox.gfx.defaultEllipse, + // dojox.gfx.defaultCircle, + // dojox.gfx.defaultLine, + // or dojox.gfx.defaultImage) + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + for(var i in this.shape){ + if(i != "type"){ this.rawNode.setAttribute(i, this.shape[i]); } + } + return this; // self + }, + + // move family + + _moveToFront: function(){ + // summary: moves a shape to front of its parent's list of shapes (SVG) + this.rawNode.parentNode.appendChild(this.rawNode); + return this; // self + }, + _moveToBack: function(){ + // summary: moves a shape to back of its parent's list of shapes (SVG) + this.rawNode.parentNode.insertBefore(this.rawNode, this.rawNode.parentNode.firstChild); + return this; // self + } +}); + +dojo.declare("dojox.gfx.Group", dojox.gfx.Shape, { + // summary: a group shape (SVG), which can be used + // to logically group shapes (e.g, to propagate matricies) + constructor: function(){ + dojox.gfx.svg.Container._init.call(this); + }, + setRawNode: function(rawNode){ + // summary: sets a raw SVG node to be used by this shape + // rawNode: Node: an SVG node + this.rawNode = rawNode; + } +}); +dojox.gfx.Group.nodeType = "g"; + +dojo.declare("dojox.gfx.Rect", dojox.gfx.shape.Rect, { + // summary: a rectangle shape (SVG) + setShape: function(newShape){ + // summary: sets a rectangle shape object (SVG) + // newShape: Object: a rectangle shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + for(var i in this.shape){ + if(i != "type" && i != "r"){ this.rawNode.setAttribute(i, this.shape[i]); } + } + if(this.shape.r){ + this.rawNode.setAttribute("ry", this.shape.r); + this.rawNode.setAttribute("rx", this.shape.r); + } + return this; // self + } +}); +dojox.gfx.Rect.nodeType = "rect"; + +dojox.gfx.Ellipse = dojox.gfx.shape.Ellipse; +dojox.gfx.Ellipse.nodeType = "ellipse"; + +dojox.gfx.Circle = dojox.gfx.shape.Circle; +dojox.gfx.Circle.nodeType = "circle"; + +dojox.gfx.Line = dojox.gfx.shape.Line; +dojox.gfx.Line.nodeType = "line"; + +dojo.declare("dojox.gfx.Polyline", dojox.gfx.shape.Polyline, { + // summary: a polyline/polygon shape (SVG) + setShape: function(points, closed){ + // summary: sets a polyline/polygon shape object (SVG) + // points: Object: a polyline/polygon shape object + if(points && points instanceof Array){ + // branch + // points: Array: an array of points + this.shape = dojox.gfx.makeParameters(this.shape, { points: points }); + if(closed && this.shape.points.length){ + this.shape.points.push(this.shape.points[0]); + } + }else{ + this.shape = dojox.gfx.makeParameters(this.shape, points); + } + this.box = null; + var attr = [], p = this.shape.points; + for(var i = 0; i < p.length; ++i){ + if(typeof p[i] == "number"){ + attr.push(p[i].toFixed(8)); + }else{ + attr.push(p[i].x.toFixed(8)); + attr.push(p[i].y.toFixed(8)); + } + } + this.rawNode.setAttribute("points", attr.join(" ")); + return this; // self + } +}); +dojox.gfx.Polyline.nodeType = "polyline"; + +dojo.declare("dojox.gfx.Image", dojox.gfx.shape.Image, { + // summary: an image (SVG) + setShape: function(newShape){ + // summary: sets an image shape object (SVG) + // newShape: Object: an image shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var rawNode = this.rawNode; + for(var i in this.shape){ + if(i != "type" && i != "src"){ rawNode.setAttribute(i, this.shape[i]); } + } + rawNode.setAttributeNS(dojox.gfx.svg.xmlns.xlink, "href", this.shape.src); + return this; // self + } +}); +dojox.gfx.Image.nodeType = "image"; + +dojo.declare("dojox.gfx.Text", dojox.gfx.shape.Text, { + // summary: an anchored text (SVG) + setShape: function(newShape){ + // summary: sets a text shape object (SVG) + // newShape: Object: a text shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var r = this.rawNode, s = this.shape; + r.setAttribute("x", s.x); + r.setAttribute("y", s.y); + r.setAttribute("text-anchor", s.align); + r.setAttribute("text-decoration", s.decoration); + r.setAttribute("rotate", s.rotated ? 90 : 0); + r.setAttribute("kerning", s.kerning ? "auto" : 0); + r.setAttribute("text-rendering", "optimizeLegibility"); + r.textContent = s.text; + return this; // self + }, + getTextWidth: function(){ + // summary: get the text width in pixels + var rawNode = this.rawNode, + oldParent = rawNode.parentNode, + _measurementNode = rawNode.cloneNode(true); + _measurementNode.style.visibility = "hidden"; + + // solution to the "orphan issue" in FF + var _width = 0, _text = _measurementNode.firstChild.nodeValue; + oldParent.appendChild(_measurementNode); + + // solution to the "orphan issue" in Opera + // (nodeValue == "" hangs firefox) + if(_text!=""){ + while(!_width){ + _width = parseInt(_measurementNode.getBBox().width); + } + } + oldParent.removeChild(_measurementNode); + return _width; + } +}); +dojox.gfx.Text.nodeType = "text"; + +dojo.declare("dojox.gfx.Path", dojox.gfx.path.Path, { + // summary: a path shape (SVG) + _updateWithSegment: function(segment){ + // summary: updates the bounding box of path with new segment + // segment: Object: a segment + dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments); + if(typeof(this.shape.path) == "string"){ + this.rawNode.setAttribute("d", this.shape.path); + } + }, + setShape: function(newShape){ + // summary: forms a path using a shape (SVG) + // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath) + dojox.gfx.Path.superclass.setShape.apply(this, arguments); + this.rawNode.setAttribute("d", this.shape.path); + return this; // self + } +}); +dojox.gfx.Path.nodeType = "path"; + +dojo.declare("dojox.gfx.TextPath", dojox.gfx.path.TextPath, { + // summary: a textpath shape (SVG) + _updateWithSegment: function(segment){ + // summary: updates the bounding box of path with new segment + // segment: Object: a segment + dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments); + this._setTextPath(); + }, + setShape: function(newShape){ + // summary: forms a path using a shape (SVG) + // newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath) + dojox.gfx.Path.superclass.setShape.apply(this, arguments); + this._setTextPath(); + return this; // self + }, + _setTextPath: function(){ + if(typeof this.shape.path != "string"){ return; } + var r = this.rawNode; + if(!r.firstChild){ + var tp = document.createElementNS(dojox.gfx.svg.xmlns.svg, "textPath"), + tx = document.createTextNode(""); + tp.appendChild(tx); + r.appendChild(tp); + } + var ref = r.firstChild.getAttributeNS(dojox.gfx.svg.xmlns.xlink, "href"), + path = ref && dojox.gfx.svg.getRef(ref); + if(!path){ + var surface = this._getParentSurface(); + if(surface){ + var defs = surface.defNode; + path = document.createElementNS(dojox.gfx.svg.xmlns.svg, "path"); + var id = dojox.gfx._base._getUniqueId(); + path.setAttribute("id", id); + defs.appendChild(path); + r.firstChild.setAttributeNS(dojox.gfx.svg.xmlns.xlink, "href", "#" + id); + } + } + if(path){ + path.setAttribute("d", this.shape.path); + } + }, + _setText: function(){ + var r = this.rawNode; + if(!r.firstChild){ + var tp = document.createElementNS(dojox.gfx.svg.xmlns.svg, "textPath"), + tx = document.createTextNode(""); + tp.appendChild(tx); + r.appendChild(tp); + } + r = r.firstChild; + var t = this.text; + r.setAttribute("alignment-baseline", "middle"); + switch(t.align){ + case "middle": + r.setAttribute("text-anchor", "middle"); + r.setAttribute("startOffset", "50%"); + break; + case "end": + r.setAttribute("text-anchor", "end"); + r.setAttribute("startOffset", "100%"); + break; + default: + r.setAttribute("text-anchor", "start"); + r.setAttribute("startOffset", "0%"); + break; + } + //r.parentNode.setAttribute("alignment-baseline", "central"); + //r.setAttribute("dominant-baseline", "central"); + r.setAttribute("baseline-shift", "0.5ex"); + r.setAttribute("text-decoration", t.decoration); + r.setAttribute("rotate", t.rotated ? 90 : 0); + r.setAttribute("kerning", t.kerning ? "auto" : 0); + r.firstChild.data = t.text; + } +}); +dojox.gfx.TextPath.nodeType = "text"; + +dojo.declare("dojox.gfx.Surface", dojox.gfx.shape.Surface, { + // summary: a surface object to be used for drawings (SVG) + constructor: function(){ + dojox.gfx.svg.Container._init.call(this); + }, + setDimensions: function(width, height){ + // summary: sets the width and height of the rawNode + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + if(!this.rawNode){ return this; } + this.rawNode.setAttribute("width", width); + this.rawNode.setAttribute("height", height); + return this; // self + }, + getDimensions: function(){ + // summary: returns an object with properties "width" and "height" + return this.rawNode ? {width: this.rawNode.getAttribute("width"), height: this.rawNode.getAttribute("height")} : null; // Object + } +}); + +dojox.gfx.createSurface = function(parentNode, width, height){ + // summary: creates a surface (SVG) + // parentNode: Node: a parent node + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + + var s = new dojox.gfx.Surface(); + s.rawNode = document.createElementNS(dojox.gfx.svg.xmlns.svg, "svg"); + s.rawNode.setAttribute("width", width); + s.rawNode.setAttribute("height", height); + + var node = document.createElementNS(dojox.gfx.svg.xmlns.svg, "defs"); + s.rawNode.appendChild(node); + s.defNode = node; + + dojo.byId(parentNode).appendChild(s.rawNode); + return s; // dojox.gfx.Surface +}; + +// Extenders + +dojox.gfx.svg.Font = { + _setFont: function(){ + // summary: sets a font object (SVG) + var f = this.fontStyle; + // next line doesn't work in Firefox 2 or Opera 9 + //this.rawNode.setAttribute("font", dojox.gfx.makeFontString(this.fontStyle)); + this.rawNode.setAttribute("font-style", f.style); + this.rawNode.setAttribute("font-variant", f.variant); + this.rawNode.setAttribute("font-weight", f.weight); + this.rawNode.setAttribute("font-size", f.size); + this.rawNode.setAttribute("font-family", f.family); + } +}; + +dojox.gfx.svg.Container = { + _init: function(){ + dojox.gfx.shape.Container._init.call(this); + }, + add: function(shape){ + // summary: adds a shape to a group/surface + // shape: dojox.gfx.Shape: an VML shape object + if(this != shape.getParent()){ + this.rawNode.appendChild(shape.rawNode); + //dojox.gfx.Group.superclass.add.apply(this, arguments); + //this.inherited(arguments); + dojox.gfx.shape.Container.add.apply(this, arguments); + } + return this; // self + }, + remove: function(shape, silently){ + // summary: remove a shape from a group/surface + // shape: dojox.gfx.Shape: an VML shape object + // silently: Boolean?: if true, regenerate a picture + if(this == shape.getParent()){ + if(this.rawNode == shape.rawNode.parentNode){ + this.rawNode.removeChild(shape.rawNode); + } + //dojox.gfx.Group.superclass.remove.apply(this, arguments); + //this.inherited(arguments); + dojox.gfx.shape.Container.remove.apply(this, arguments); + } + return this; // self + }, + clear: function(){ + // summary: removes all shapes from a group/surface + var r = this.rawNode; + while(r.lastChild){ + r.removeChild(r.lastChild); + } + var d = this.defNode; + if(d){ + while(d.lastChild){ + d.removeChild(d.lastChild); + } + r.appendChild(d); + } + //return this.inherited(arguments); // self + return dojox.gfx.shape.Container.clear.apply(this, arguments); + }, + _moveChildToFront: dojox.gfx.shape.Container._moveChildToFront, + _moveChildToBack: dojox.gfx.shape.Container._moveChildToBack +}; + +dojo.mixin(dojox.gfx.shape.Creator, { + // summary: SVG shape creators + createObject: function(shapeType, rawShape){ + // summary: creates an instance of the passed shapeType class + // shapeType: Function: a class constructor to create an instance of + // rawShape: Object: properties to be passed in to the classes "setShape" method + if(!this.rawNode){ return null; } + var shape = new shapeType(), + node = document.createElementNS(dojox.gfx.svg.xmlns.svg, shapeType.nodeType); + shape.setRawNode(node); + this.rawNode.appendChild(node); + shape.setShape(rawShape); + this.add(shape); + return shape; // dojox.gfx.Shape + } +}); + +dojo.extend(dojox.gfx.Text, dojox.gfx.svg.Font); +dojo.extend(dojox.gfx.TextPath, dojox.gfx.svg.Font); + +dojo.extend(dojox.gfx.Group, dojox.gfx.svg.Container); +dojo.extend(dojox.gfx.Group, dojox.gfx.shape.Creator); + +dojo.extend(dojox.gfx.Surface, dojox.gfx.svg.Container); +dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator); + +} diff --git a/includes/js/dojox/gfx/svg_attach.js b/includes/js/dojox/gfx/svg_attach.js new file mode 100644 index 0000000..7ec9ed8 --- /dev/null +++ b/includes/js/dojox/gfx/svg_attach.js @@ -0,0 +1,224 @@ +dojo.require("dojox.gfx.svg"); + +dojo.experimental("dojox.gfx.svg_attach"); + +(function(){ + dojox.gfx.attachNode = function(node){ + // summary: creates a shape from a Node + // node: Node: an SVG node + if(!node) return null; + var s = null; + switch(node.tagName.toLowerCase()){ + case dojox.gfx.Rect.nodeType: + s = new dojox.gfx.Rect(node); + attachRect(s); + break; + case dojox.gfx.Ellipse.nodeType: + s = new dojox.gfx.Ellipse(node); + attachShape(s, dojox.gfx.defaultEllipse); + break; + case dojox.gfx.Polyline.nodeType: + s = new dojox.gfx.Polyline(node); + attachShape(s, dojox.gfx.defaultPolyline); + break; + case dojox.gfx.Path.nodeType: + s = new dojox.gfx.Path(node); + attachShape(s, dojox.gfx.defaultPath); + break; + case dojox.gfx.Circle.nodeType: + s = new dojox.gfx.Circle(node); + attachShape(s, dojox.gfx.defaultCircle); + break; + case dojox.gfx.Line.nodeType: + s = new dojox.gfx.Line(node); + attachShape(s, dojox.gfx.defaultLine); + break; + case dojox.gfx.Image.nodeType: + s = new dojox.gfx.Image(node); + attachShape(s, dojox.gfx.defaultImage); + break; + case dojox.gfx.Text.nodeType: + var t = node.getElementsByTagName("textPath"); + if(t && t.length){ + s = new dojox.gfx.TextPath(node); + attachShape(s, dojox.gfx.defaultPath); + attachTextPath(s); + }else{ + s = new dojox.gfx.Text(node); + attachText(s); + } + attachFont(s); + break; + default: + //console.debug("FATAL ERROR! tagName = " + node.tagName); + return null; + } + if(!(s instanceof dojox.gfx.Image)){ + attachFill(s); + attachStroke(s); + } + attachTransform(s); + return s; // dojox.gfx.Shape + }; + + dojox.gfx.attachSurface = function(node){ + // summary: creates a surface from a Node + // node: Node: an SVG node + var s = new dojox.gfx.Surface(); + s.rawNode = node; + var def_elems = node.getElementsByTagName("defs"); + if(def_elems.length == 0){ + return null; // dojox.gfx.Surface + } + s.defNode = def_elems[0]; + return s; // dojox.gfx.Surface + }; + + var attachFill = function(object){ + // summary: deduces a fill style from a node. + // object: dojox.gfx.Shape: an SVG shape + var fill = object.rawNode.getAttribute("fill"); + if(fill == "none"){ + object.fillStyle = null; + return; + } + var fillStyle = null, gradient = dojox.gfx.svg.getRef(fill); + if(ref){ + switch(gradient.tagName.toLowerCase()){ + case "lineargradient": + fillStyle = _getGradient(dojox.gfx.defaultLinearGradient, gradient); + dojo.forEach(["x1", "y1", "x2", "y2"], function(x){ + fillStyle[x] = gradient.getAttribute(x); + }); + break; + case "radialgradient": + fillStyle = _getGradient(dojox.gfx.defaultRadialGradient, gradient); + dojo.forEach(["cx", "cy", "r"], function(x){ + fillStyle[x] = gradient.getAttribute(x); + }); + fillStyle.cx = gradient.getAttribute("cx"); + fillStyle.cy = gradient.getAttribute("cy"); + fillStyle.r = gradient.getAttribute("r"); + break; + case "pattern": + fillStyle = dojo.lang.shallowCopy(dojox.gfx.defaultPattern, true); + dojo.forEach(["x", "y", "width", "height"], function(x){ + fillStyle[x] = gradient.getAttribute(x); + }); + fillStyle.src = gradient.firstChild.getAttributeNS(dojox.gfx.svg.xmlns.xlink, "href"); + break; + } + }else{ + fillStyle = new dojo.Color(fill); + var opacity = rawNode.getAttribute("fill-opacity"); + if(opacity != null){ fillStyle.a = opacity; } + } + object.fillStyle = fillStyle; + }; + + var _getGradient = function(defaultGradient, gradient){ + var fillStyle = dojo.clone(defaultGradient); + fillStyle.colors = []; + for(var i = 0; i < gradient.childNodes.length; ++i){ + fillStyle.colors.push({ + offset: gradient.childNodes[i].getAttribute("offset"), + color: new dojo.Color(gradient.childNodes[i].getAttribute("stop-color")) + }); + } + return fillStyle; + }; + + var attachStroke = function(object){ + // summary: deduces a stroke style from a node. + // object: dojox.gfx.Shape: an SVG shape + var rawNode = object.rawNode, stroke = rawNode.getAttribute("stroke"); + if(stroke == null || stroke == "none"){ + object.strokeStyle = null; + return; + } + var strokeStyle = object.strokeStyle = dojo.clone(dojox.gfx.defaultStroke); + var color = new dojo.Color(stroke); + if(color){ + strokeStyle.color = color; + strokeStyle.color.a = rawNode.getAttribute("stroke-opacity"); + strokeStyle.width = rawNode.getAttribute("stroke-width"); + strokeStyle.cap = rawNode.getAttribute("stroke-linecap"); + strokeStyle.join = rawNode.getAttribute("stroke-linejoin"); + if(strokeStyle.join == "miter"){ + strokeStyle.join = rawNode.getAttribute("stroke-miterlimit"); + } + strokeStyle.style = rawNode.getAttribute("dojoGfxStrokeStyle"); + } + }; + + var attachTransform = function(object){ + // summary: deduces a transformation matrix from a node. + // object: dojox.gfx.Shape: an SVG shape + var matrix = object.rawNode.getAttribute("transform"); + if(matrix.match(/^matrix\(.+\)$/)){ + var t = matrix.slice(7, -1).split(","); + object.matrix = dojox.gfx.matrix.normalize({ + xx: parseFloat(t[0]), xy: parseFloat(t[2]), + yx: parseFloat(t[1]), yy: parseFloat(t[3]), + dx: parseFloat(t[4]), dy: parseFloat(t[5]) + }); + }else{ + object.matrix = null; + } + }; + + var attachFont = function(object){ + // summary: deduces a font style from a Node. + // object: dojox.gfx.Shape: an SVG shape + var fontStyle = object.fontStyle = dojo.clone(dojox.gfx.defaultFont), + r = object.rawNode; + fontStyle.style = r.getAttribute("font-style"); + fontStyle.variant = r.getAttribute("font-variant"); + fontStyle.weight = r.getAttribute("font-weight"); + fontStyle.size = r.getAttribute("font-size"); + fontStyle.family = r.getAttribute("font-family"); + }; + + var attachShape = function(object, def){ + // summary: builds a shape from a node. + // object: dojox.gfx.Shape: an SVG shape + // def: Object: a default shape template + var shape = object.shape = dojo.clone(def), r = object.rawNode; + for(var i in shape) { + shape[i] = r.getAttribute(i); + } + }; + + var attachRect = function(object){ + // summary: builds a rectangle shape from a node. + // object: dojox.gfx.Shape: an SVG shape + attachShape(object, dojox.gfx.defaultRect); + object.shape.r = Math.min(object.rawNode.getAttribute("rx"), object.rawNode.getAttribute("ry")); + }; + + var attachText = function(object){ + // summary: builds a text shape from a node. + // object: dojox.gfx.Shape: an SVG shape + var shape = object.shape = dojo.clone(dojox.gfx.defaultText), + r = object.rawNode; + shape.x = r.getAttribute("x"); + shape.y = r.getAttribute("y"); + shape.align = r.getAttribute("text-anchor"); + shape.decoration = r.getAttribute("text-decoration"); + shape.rotated = parseFloat(r.getAttribute("rotate")) != 0; + shape.kerning = r.getAttribute("kerning") == "auto"; + shape.text = r.firstChild.nodeValue; + }; + + var attachTextPath = function(object){ + // summary: builds a textpath shape from a node. + // object: dojox.gfx.Shape: an SVG shape + var shape = object.shape = dojo.clone(dojox.gfx.defaultTextPath), + r = object.rawNode; + shape.align = r.getAttribute("text-anchor"); + shape.decoration = r.getAttribute("text-decoration"); + shape.rotated = parseFloat(r.getAttribute("rotate")) != 0; + shape.kerning = r.getAttribute("kerning") == "auto"; + shape.text = r.firstChild.nodeValue; + }; +})(); diff --git a/includes/js/dojox/gfx/tests/decompose.js b/includes/js/dojox/gfx/tests/decompose.js new file mode 100644 index 0000000..b488bdd --- /dev/null +++ b/includes/js/dojox/gfx/tests/decompose.js @@ -0,0 +1,114 @@ +if(!dojo._hasResource["dojox.gfx.tests.decompose"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.tests.decompose"] = true; +dojo.provide("dojox.gfx.tests.decompose"); +dojo.require("dojox.gfx.decompose"); + +(function(){ + var m = dojox.gfx.matrix; + var eq = function(t, a, b){ t.t(2 * Math.abs(a - b) / ((a < 1 && b < 1) ? 1 : a + b) < 1e-6); }; + var eqM = function(t, a, b){ + eq(t, a.xx, b.xx); + eq(t, a.yy, b.yy); + eq(t, a.xy, b.xy); + eq(t, a.yx, b.yx); + eq(t, a.dx, b.dx); + eq(t, a.dy, b.dy); + }; + var compose = function(r){ + return m.normalize([ + m.translate(r.dx, r.dy), + m.rotate(r.angle2), + m.scale(r.sx, r.sy), + m.rotate(r.angle1) + ]); + }; + var reconstruct = function(a){ + return compose(dojox.gfx.decompose(a)); + }; + var compare = function(t, a){ + var A = m.normalize(a); + eqM(t, A, reconstruct(A)); + }; + tests.register("dojox.gfx.tests.decompose", [ + function IdentityTest(t){ + compare(t, m.identity); + }, + function FlipXTest(t){ + compare(t, m.flipX); + }, + function FlipYTest(t){ + compare(t, m.flipY); + }, + function FlipXYTest(t){ + compare(t, m.flipXY); + }, + function TranslationTest(t){ + compare(t, m.translate(45, -15)); + }, + function RotationTest(t){ + compare(t, m.rotateg(35)); + }, + function SkewXTest(t){ + compare(t, m.skewXg(35)); + }, + function SkewYTest(t){ + compare(t, m.skewYg(35)); + }, + function ReflectTest(t){ + compare(t, m.reflect(13, 27)); + }, + function ProjectTest(t){ + compare(t, m.project(13, 27)); + }, + function ScaleTest1(t){ + compare(t, m.scale(3)); + }, + function ScaleTest2(t){ + compare(t, m.scale(3, -1)); + }, + function ScaleTest3(t){ + compare(t, m.scale(-3, 1)); + }, + function ScaleTest4(t){ + compare(t, m.scale(-3, -1)); + }, + function ScaleRotateTest1(t){ + compare(t, [m.scale(3), m.rotateAt(35, 13, 27)]); + }, + function ScaleRotateTest2(t){ + compare(t, [m.scale(3, -1), m.rotateAt(35, 13, 27)]); + }, + function ScaleRotateTest3(t){ + compare(t, [m.scale(-3, 1), m.rotateAt(35, 13, 27)]); + }, + function ScaleRotateTest4(t){ + compare(t, [m.scale(-3, -1), m.rotateAt(35, 13, 27)]); + }, + function RotateScaleTest1(t){ + compare(t, [m.rotateAt(35, 13, 27), m.scale(3)]); + }, + function RotateScaleTest2(t){ + compare(t, [m.rotateAt(35, 13, 27), m.scale(3, -1)]); + }, + function RotateScaleTest3(t){ + compare(t, [m.rotateAt(35, 13, 27), m.scale(-3, 1)]); + }, + function RotateScaleTest4(t){ + compare(t, [m.rotateAt(35, 13, 27), m.scale(-3, -1)]); + }, + function RotateScaleRotateTest1(t){ + compare(t, [m.rotateAt(35, 13, 27), m.scale(3), m.rotateAt(-15, 163, -287)]); + }, + function RotateScaleRotateTest2(t){ + compare(t, [m.rotateAt(35, 13, 27), m.scale(3, -1), m.rotateAt(-15, 163, -287)]); + }, + function RotateScaleRotateTest3(t){ + compare(t, [m.rotateAt(35, 13, 27), m.scale(-3, 1), m.rotateAt(-15, 163, -287)]); + }, + function RotateScaleRotateTest4(t){ + compare(t, [m.rotateAt(35, 13, 27), m.scale(-3, -1), m.rotateAt(-15, 163, -287)]); + } + ]); +})(); + +} diff --git a/includes/js/dojox/gfx/tests/matrix.js b/includes/js/dojox/gfx/tests/matrix.js new file mode 100644 index 0000000..282ec36 --- /dev/null +++ b/includes/js/dojox/gfx/tests/matrix.js @@ -0,0 +1,228 @@ +if(!dojo._hasResource["dojox.gfx.tests.matrix"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.tests.matrix"] = true; +dojo.provide("dojox.gfx.tests.matrix"); +dojo.require("dojox.gfx.matrix"); + +(function(){ + var m = dojox.gfx.matrix; + var eq = function(t, a, b){ t.t(2 * Math.abs(a - b) / ((a < 1 && b < 1) ? 1 : a + b) < 1e-6); }; + tests.register("dojox.gfx.tests.matrix", [ + function IdentityTest(t){ + var a = new m.Matrix2D(); + eq(t, a.xx, 1); + eq(t, a.yy, 1); + eq(t, a.xy, 0); + eq(t, a.yx, 0); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + }, + function Rot30gTest(t){ + var a = m.rotateg(30); + eq(t, a.xx, a.yy); + eq(t, a.xy, -a.yx); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + eq(t, a.yx, 0.5); + t.t(a.xy < 0); + t.t(a.yx > 0); + }, + function Rot45gTest(t){ + var a = m.rotateg(45); + eq(t, a.xx, a.yy); + eq(t, a.xy, -a.yx); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + eq(t, a.xx, a.yx); + eq(t, a.yy, -a.xy); + }, + function Rot90gTest(t){ + var a = m.rotateg(90); + eq(t, a.xx, a.yy); + eq(t, a.xy, -a.yx); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + eq(t, a.xx, 0); + eq(t, a.yx, 1); + }, + function CombineIdentitiesTest(t){ + var a = m.normalize([new m.Matrix2D(), new m.Matrix2D(), new m.Matrix2D()]); + eq(t, a.xx, 1); + eq(t, a.yy, 1); + eq(t, a.xy, 0); + eq(t, a.yx, 0); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + }, + function CombineExclusiveTest(t){ + var a = m.normalize([m.rotateg(30), m.rotateg(-30)]); + eq(t, a.xx, 1); + eq(t, a.yy, 1); + eq(t, a.xy, 0); + eq(t, a.yx, 0); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + }, + function CombineInvertedTest(t){ + var a = m.normalize([m.rotateg(30), m.invert(m.rotateg(30))]); + eq(t, a.xx, 1); + eq(t, a.yy, 1); + eq(t, a.xy, 0); + eq(t, a.yx, 0); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + }, + function Rot90gAtTest(t){ + var a = m.rotategAt(90, 10, 10); + eq(t, a.xx, a.yy); + eq(t, a.xy, -a.yx); + eq(t, a.dx, 20); + eq(t, a.dy, 0); + eq(t, a.xx, 0); + eq(t, a.yx, 1); + }, + function MultPointTest1(t){ + var b = m.multiplyPoint(m.rotategAt(90, 10, 10), 10, 10); + eq(t, b.x, 10); + eq(t, b.y, 10); + }, + function MultPointTest2(t){ + var b = m.multiplyPoint(m.rotategAt(90, 10, 10), {x: 10, y: 5}); + eq(t, b.x, 15); + eq(t, b.y, 10); + }, + function MultPointTest3(t){ + var b = m.multiplyPoint(m.rotategAt(90, 10, 10), 10, 15); + eq(t, b.x, 5); + eq(t, b.y, 10); + }, + function ScaleTest1(t){ + var a = m.normalize([m.scale(2, 1), m.invert(m.rotateg(45))]); + eq(t, a.xx, 2 * a.yy); + eq(t, a.xy, -2 * a.yx); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + eq(t, a.xx, a.xy); + eq(t, a.yy, -a.yx); + }, + function ScaleTest2(t){ + var a = m.normalize([m.scale(1, 2), m.invert(m.rotateg(45))]); + eq(t, 2 * a.xx, a.yy); + eq(t, 2 * a.xy, -a.yx); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + eq(t, a.xx, a.xy); + eq(t, a.yy, -a.yx); + }, + function ScaleTest3(t){ + var a = m.normalize([m.rotateg(45), m.scale(2, 1)]); + eq(t, a.xx, 2 * a.yy); + eq(t, a.yx, -2 * a.xy); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + eq(t, a.xx, a.yx); + eq(t, a.yy, -a.xy); + }, + function ScaleTest4(t){ + var a = m.normalize([m.rotateg(45), m.scale(1, 2)]); + eq(t, 2 * a.xx, a.yy); + eq(t, 2 * a.yx, -a.xy); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + eq(t, a.xx, a.yx); + eq(t, a.yy, -a.xy); + }, + function ScaleTest5(t){ + var a = m.normalize([m.rotategAt(45, 100, 100), m.scale(2)]); + eq(t, a.xx, a.yy); + eq(t, a.xy, -a.yx); + eq(t, a.xx, a.yx); + eq(t, a.yy, -a.xy); + eq(t, a.dx, 100); + t.t(a.dy < 0); + var b = m.normalize([m.scale(2), m.rotategAt(45, 100, 100)]); + eq(t, b.xx, b.yy); + eq(t, b.xy, -b.yx); + eq(t, b.xx, b.yx); + eq(t, b.yy, -b.xy); + eq(t, b.dx, 200); + t.t(b.dy < 0); + eq(t, a.xx, b.xx); + eq(t, a.xy, b.xy); + eq(t, a.yx, b.yx); + eq(t, a.yy, b.yy); + eq(t, 2 * a.dx, b.dx); + eq(t, 2 * a.dy, b.dy); + var c = m.normalize([m.rotateg(45), m.scale(2)]); + eq(t, c.xx, c.yy); + eq(t, c.xy, -c.yx); + eq(t, c.xx, c.yx); + eq(t, c.yy, -c.xy); + eq(t, c.dx, 0); + eq(t, c.dy, 0); + var d = m.normalize([m.scale(2), m.rotateg(45)]); + eq(t, d.xx, d.yy); + eq(t, d.xy, -d.yx); + eq(t, d.xx, d.yx); + eq(t, d.yy, -d.xy); + eq(t, d.dx, 0); + eq(t, d.dy, 0); + eq(t, a.xx, c.xx); + eq(t, a.xy, c.xy); + eq(t, a.yx, c.yx); + eq(t, a.yy, c.yy); + eq(t, a.xx, d.xx); + eq(t, a.xy, d.xy); + eq(t, a.yx, d.yx); + eq(t, a.yy, d.yy); + }, + function ScaleTest6(t){ + var a = m.normalize(6); + eq(t, a.xx, 6); + eq(t, a.yy, 6); + eq(t, a.xy, 0); + eq(t, a.yx, 0); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + }, + function ScaleTest7(t){ + var a = m.normalize([2, m.scale(2, 1)]); + eq(t, a.xx, 4); + eq(t, a.yy, 2); + eq(t, a.xy, 0); + eq(t, a.yx, 0); + eq(t, a.dx, 0); + eq(t, a.dy, 0); + }, + function TranslateTest(t){ + var a = m.normalize({dx: 100, dy: 200}); + eq(t, a.xx, 1); + eq(t, a.yy, 1); + eq(t, a.xy, 0); + eq(t, a.yx, 0); + eq(t, a.dx, 100); + eq(t, a.dy, 200); + }, + function ReflectTest1(t){ + var b = m.multiplyPoint(m.reflect(1, 1), 1, 0); + eq(t, b.x, 0); + eq(t, b.y, 1); + }, + function ReflectTest2(t){ + var b = m.multiplyPoint(m.reflect(1, 1), 0, 1); + eq(t, b.x, 1); + eq(t, b.y, 0); + }, + function ProjectTest1(t){ + var b = m.multiplyPoint(m.project(1, 1), 1, 0); + eq(t, b.x, 0.5); + eq(t, b.y, 0.5); + }, + function ProjectTest2(t){ + var b = m.multiplyPoint(m.project(1, 1), 0, 1); + eq(t, b.x, 0.5); + eq(t, b.y, 0.5); + } + ]); +})(); + +} diff --git a/includes/js/dojox/gfx/tests/module.js b/includes/js/dojox/gfx/tests/module.js new file mode 100644 index 0000000..0790b6b --- /dev/null +++ b/includes/js/dojox/gfx/tests/module.js @@ -0,0 +1,13 @@ +if(!dojo._hasResource["dojox.gfx.tests.module"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.tests.module"] = true; +dojo.provide("dojox.gfx.tests.module"); + +try{ + dojo.require("dojox.gfx.tests.matrix"); + dojo.require("dojox.gfx.tests.decompose"); +}catch(e){ + doh.debug(e); +} + + +} diff --git a/includes/js/dojox/gfx/tests/runTests.html b/includes/js/dojox/gfx/tests/runTests.html new file mode 100644 index 0000000..4e13179 --- /dev/null +++ b/includes/js/dojox/gfx/tests/runTests.html @@ -0,0 +1,9 @@ + + + + Dojox Unit Test Runner + + + Redirecting to D.O.H runner. + + diff --git a/includes/js/dojox/gfx/tests/test_arc.html b/includes/js/dojox/gfx/tests/test_arc.html new file mode 100644 index 0000000..f7fc589 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_arc.html @@ -0,0 +1,71 @@ + + +Testing arc + + + + + + + + + + + + + + + +

Testing arc

+ +
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_bezier.html b/includes/js/dojox/gfx/tests/test_bezier.html new file mode 100644 index 0000000..bcee2d0 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_bezier.html @@ -0,0 +1,85 @@ + + +Approximation of an arc with bezier + + + + + + + + + + + + + + + +

Approximation of an arc with bezier

+ +
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_decompose.html b/includes/js/dojox/gfx/tests/test_decompose.html new file mode 100644 index 0000000..6291cc2 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_decompose.html @@ -0,0 +1,54 @@ + + +Testing decompose + + + + + + + + +

Testing decompose

+

+ Example: m.rotategAt(30, 100, 100), m.scaleAt(2, 3, 5, 5), m.rotate(45)
+ +

+

Result:

+

+ Original matrix
+ +

+

+ Decomposed matrix
+ +

+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_fill.html b/includes/js/dojox/gfx/tests/test_fill.html new file mode 100644 index 0000000..84827ea --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_fill.html @@ -0,0 +1,47 @@ + + +Testing fill rule + + + + + + + + + + + + + +

Testing fill rule

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_fx.html b/includes/js/dojox/gfx/tests/test_fx.html new file mode 100644 index 0000000..c7b5b81 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_fx.html @@ -0,0 +1,113 @@ + + + +Testing animation + + + + + + + + + + + + + +

Testing animation

+

+ +   + +   + +   + +

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_gfx.html b/includes/js/dojox/gfx/tests/test_gfx.html new file mode 100644 index 0000000..6d2bef3 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_gfx.html @@ -0,0 +1,489 @@ + + +Dojo Unified 2D Graphics + + + + + + + + + + + + + +

dojox.gfx tests

+ + + +
+ + diff --git a/includes/js/dojox/gfx/tests/test_gradient.html b/includes/js/dojox/gfx/tests/test_gradient.html new file mode 100644 index 0000000..cd4e772 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_gradient.html @@ -0,0 +1,70 @@ + + +Dojo Unified 2D Graphics + + + + + + + + + + + +

dojox.gfx Alpha gradient test

+
+ + diff --git a/includes/js/dojox/gfx/tests/test_group.html b/includes/js/dojox/gfx/tests/test_group.html new file mode 100644 index 0000000..fe11b37 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_group.html @@ -0,0 +1,73 @@ + + +Dojo Unified 2D Graphics + + + + + + + + + + + + + + +

dojox.gfx Group tests

+

+
+
+ +

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_image1.html b/includes/js/dojox/gfx/tests/test_image1.html new file mode 100644 index 0000000..41b168e --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_image1.html @@ -0,0 +1,74 @@ + + +Testing image + + + + + + + + + + +

dojox.gfx Image tests

+

Note: Silverlight doesn't allow downloading images when run from a file system. This demo should be run from a server.

+

+
+
+
+
+
+

+

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_image2.html b/includes/js/dojox/gfx/tests/test_image2.html new file mode 100644 index 0000000..25f71c0 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_image2.html @@ -0,0 +1,50 @@ + + +Testing image + + + + + + + + + +

Testing image:

+

Note: Silverlight doesn't allow downloading images when run from a file system. This demo should be run from a server.

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_linearGradient.html b/includes/js/dojox/gfx/tests/test_linearGradient.html new file mode 100644 index 0000000..f18021a --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_linearGradient.html @@ -0,0 +1,80 @@ + + +Dojo Unified 2D Graphics + + + + + + + + + + + + + + + + + +

dojox.gfx Linear Gradient test

+
+ + diff --git a/includes/js/dojox/gfx/tests/test_linestyle.html b/includes/js/dojox/gfx/tests/test_linestyle.html new file mode 100644 index 0000000..c4a422b --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_linestyle.html @@ -0,0 +1,45 @@ + + +Dojo Unified 2D Graphics + + + + + + + + + + + + + +

dojox.gfx: Line style test

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_pattern.html b/includes/js/dojox/gfx/tests/test_pattern.html new file mode 100644 index 0000000..04d5c3d --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_pattern.html @@ -0,0 +1,44 @@ + + +Testing pattern + + + + + + + + + + + + +

dojox.gfx Pattern test

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_poly.html b/includes/js/dojox/gfx/tests/test_poly.html new file mode 100644 index 0000000..7db70f1 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_poly.html @@ -0,0 +1,53 @@ + + +Testing polyline and line transforms + + + + + + + + + + + + + + + +

dojox.gfx Polyline test

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_resize.html b/includes/js/dojox/gfx/tests/test_resize.html new file mode 100644 index 0000000..3870ab0 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_resize.html @@ -0,0 +1,61 @@ + + +Testing surface resizing + + + + + + + + + + + + + + + +

Testing surface resizing

+ +

+ +   + +   + +   + +

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_setPath.html b/includes/js/dojox/gfx/tests/test_setPath.html new file mode 100644 index 0000000..c8d7749 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_setPath.html @@ -0,0 +1,76 @@ + + +Testing setPath and curves + + + + + + + + + + + +

dojox.gfx setPath and curve test

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_tbbox.html b/includes/js/dojox/gfx/tests/test_tbbox.html new file mode 100644 index 0000000..1fb1275 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_tbbox.html @@ -0,0 +1,117 @@ + + +Dojo Unified 2D Graphics + + + + + + + + + + + + + + + + +

dojox.gfx Transformation test

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_text.html b/includes/js/dojox/gfx/tests/test_text.html new file mode 100644 index 0000000..446156f --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_text.html @@ -0,0 +1,88 @@ + + +Testing text + + + + + + + + + + + +

dojox.gfx Text test

+
+
 
+

 

+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_textpath.html b/includes/js/dojox/gfx/tests/test_textpath.html new file mode 100644 index 0000000..201b0b5 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_textpath.html @@ -0,0 +1,76 @@ + + +Testing textpath + + + + + + + + + +

dojox.gfx Text on a Path test

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/tests/test_transform.html b/includes/js/dojox/gfx/tests/test_transform.html new file mode 100644 index 0000000..abc50d5 --- /dev/null +++ b/includes/js/dojox/gfx/tests/test_transform.html @@ -0,0 +1,98 @@ + + +Dojo Unified 2D Graphics + + + + + + + + + + +

dojox.gfx Transform test

+
+

That's all Folks!

+ + diff --git a/includes/js/dojox/gfx/utils.js b/includes/js/dojox/gfx/utils.js new file mode 100644 index 0000000..7ee4d9d --- /dev/null +++ b/includes/js/dojox/gfx/utils.js @@ -0,0 +1,87 @@ +if(!dojo._hasResource["dojox.gfx.utils"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.utils"] = true; +dojo.provide("dojox.gfx.utils"); + +dojo.require("dojox.gfx"); + +dojox.gfx.utils.serialize = function( + /* dojox.gfx.Surface || dojox.gfx.Shape */ object +){ + var t = {}, v, isSurface = object instanceof dojox.gfx.Surface; + if(isSurface || object instanceof dojox.gfx.Group){ + t.children = []; + for(var i = 0; i < object.children.length; ++i){ + t.children.push(dojox.gfx.utils.serialize(object.children[i])); + } + if(isSurface){ + return t.children; // Array + } + }else{ + t.shape = object.getShape(); + } + if(object.getTransform){ + v = object.getTransform(); + if(v){ t.transform = v; } + } + if(object.getStroke){ + v = object.getStroke(); + if(v){ t.stroke = v; } + } + if(object.getFill){ + v = object.getFill(); + if(v){ t.fill = v; } + } + if(object.getFont){ + v = object.getFont(); + if(v){ t.font = v; } + } + return t; // Object +}; + +dojox.gfx.utils.toJson = function( + /* dojox.gfx.Surface || dojox.gfx.Shape */ object, + /* Boolean? */ prettyPrint +){ + return dojo.toJson(dojox.gfx.utils.serialize(object), prettyPrint); // String +}; + +dojox.gfx.utils.deserialize = function( + /* dojox.gfx.Surface || dojox.gfx.Shape */ parent, + /* dojox.gfx.Shape || Array */ object +){ + if(object instanceof Array){ + var t = []; + for(var i = 0; i < object.length; ++i){ + t.push(dojox.gfx.utils.deserialize(parent, object[i])); + } + return t; // Array + } + var shape = ("shape" in object) ? parent.createShape(object.shape) : parent.createGroup(); + if("transform" in object){ + shape.setTransform(object.transform); + } + if("stroke" in object){ + shape.setStroke(object.stroke); + } + if("fill" in object){ + shape.setFill(object.fill); + } + if("font" in object){ + shape.setFont(object.font); + } + if("children" in object){ + for(var i = 0; i < object.children.length; ++i){ + dojox.gfx.utils.deserialize(shape, object.children[i]); + } + } + return shape; // dojox.gfx.Shape +}; + +dojox.gfx.utils.fromJson = function( + /* dojox.gfx.Surface || dojox.gfx.Shape */ parent, + /* String */ json +){ + return dojox.gfx.utils.deserialize(parent, dojo.fromJson(json)); // Array || dojox.gfx.Shape +}; + +} diff --git a/includes/js/dojox/gfx/vml.js b/includes/js/dojox/gfx/vml.js new file mode 100644 index 0000000..44f01db --- /dev/null +++ b/includes/js/dojox/gfx/vml.js @@ -0,0 +1,1165 @@ +if(!dojo._hasResource["dojox.gfx.vml"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. +dojo._hasResource["dojox.gfx.vml"] = true; +dojo.provide("dojox.gfx.vml"); + +dojo.require("dojox.gfx._base"); +dojo.require("dojox.gfx.shape"); +dojo.require("dojox.gfx.path"); +dojo.require("dojox.gfx.arc"); + +// dojox.gfx.vml.xmlns: String: a VML's namespace +dojox.gfx.vml.xmlns = "urn:schemas-microsoft-com:vml"; + +// dojox.gfx.vml.text_alignment: Object: mapping from SVG alignment to VML alignment +dojox.gfx.vml.text_alignment = {start: "left", middle: "center", end: "right"}; + +dojox.gfx.vml._parseFloat = function(str) { + // summary: a helper function to parse VML-specific floating-point values + // str: String: a representation of a floating-point number + return str.match(/^\d+f$/i) ? parseInt(str) / 65536 : parseFloat(str); // Number +}; + +dojox.gfx.vml._bool = {"t": 1, "true": 1}; + +dojo.extend(dojox.gfx.Shape, { + // summary: VML-specific implementation of dojox.gfx.Shape methods + + setFill: function(fill){ + // summary: sets a fill object (VML) + // fill: Object: a fill object + // (see dojox.gfx.defaultLinearGradient, + // dojox.gfx.defaultRadialGradient, + // dojox.gfx.defaultPattern, + // or dojo.Color) + + if(!fill){ + // don't fill + this.fillStyle = null; + this.rawNode.filled = "f"; + return this; + } + if(typeof fill == "object" && "type" in fill){ + // gradient + var i, f, fo, a, s; + switch(fill.type){ + case "linear": + var matrix = this._getRealMatrix(), m = dojox.gfx.matrix; + s = []; + f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill); + a = f.colors; + this.fillStyle = f; + dojo.forEach(a, function(v, i, a){ + a[i].color = dojox.gfx.normalizeColor(v.color); + }); + if(a[0].offset > 0){ + s.push("0 " + a[0].color.toHex()); + } + for(i = 0; i < a.length; ++i){ + s.push(a[i].offset.toFixed(8) + " " + a[i].color.toHex()); + } + i = a.length - 1; + if(a[i].offset < 1){ + s.push("1 " + a[i].color.toHex()); + } + fo = this.rawNode.fill; + fo.colors.value = s.join(";"); + fo.method = "sigma"; + fo.type = "gradient"; + var fc1 = matrix ? m.multiplyPoint(matrix, f.x1, f.y1) : {x: f.x1, y: f.y1}, + fc2 = matrix ? m.multiplyPoint(matrix, f.x2, f.y2) : {x: f.x2, y: f.y2}; + fo.angle = (m._radToDeg(Math.atan2(fc2.x - fc1.x, fc2.y - fc1.y)) + 180) % 360; + fo.on = true; + break; + case "radial": + f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill); + this.fillStyle = f; + var l = parseFloat(this.rawNode.style.left), + t = parseFloat(this.rawNode.style.top), + w = parseFloat(this.rawNode.style.width), + h = parseFloat(this.rawNode.style.height), + c = isNaN(w) ? 1 : 2 * f.r / w; + a = []; + // add a color at the offset 0 (1 in VML coordinates) + if(f.colors[0].offset > 0){ + a.push({offset: 1, color: dojox.gfx.normalizeColor(f.colors[0].color)}); + } + // massage colors + dojo.forEach(f.colors, function(v, i){ + a.push({offset: 1 - v.offset * c, color: dojox.gfx.normalizeColor(v.color)}); + }); + i = a.length - 1; + while(i >= 0 && a[i].offset < 0){ --i; } + if(i < a.length - 1){ + // correct excessive colors + var q = a[i], p = a[i + 1]; + p.color = dojo.blendColors(q.color, p.color, q.offset / (q.offset - p.offset)); + p.offset = 0; + while(a.length - i > 2) a.pop(); + } + // set colors + i = a.length - 1, s = []; + if(a[i].offset > 0){ + s.push("0 " + a[i].color.toHex()); + } + for(; i >= 0; --i){ + s.push(a[i].offset.toFixed(8) + " " + a[i].color.toHex()); + } + fo = this.rawNode.fill; + fo.colors.value = s.join(";"); + fo.method = "sigma"; + fo.type = "gradientradial"; + if(isNaN(w) || isNaN(h) || isNaN(l) || isNaN(t)){ + fo.focusposition = "0.5 0.5"; + }else{ + fo.focusposition = ((f.cx - l) / w).toFixed(8) + " " + ((f.cy - t) / h).toFixed(8); + } + fo.focussize = "0 0"; + fo.on = true; + break; + case "pattern": + f = dojox.gfx.makeParameters(dojox.gfx.defaultPattern, fill); + this.fillStyle = f; + fo = this.rawNode.fill; + fo.type = "tile"; + fo.src = f.src; + if(f.width && f.height){ + // in points + fo.size.x = dojox.gfx.px2pt(f.width); + fo.size.y = dojox.gfx.px2pt(f.height); + } + fo.alignShape = "f"; + fo.position.x = 0; + fo.position.y = 0; + fo.origin.x = f.width ? f.x / f.width : 0; + fo.origin.y = f.height ? f.y / f.height : 0; + fo.on = true; + break; + } + this.rawNode.fill.opacity = 1; + return this; + } + // color object + this.fillStyle = dojox.gfx.normalizeColor(fill); + this.rawNode.fill.method = "any"; + this.rawNode.fill.type = "solid"; + this.rawNode.fillcolor = this.fillStyle.toHex(); + this.rawNode.fill.opacity = this.fillStyle.a; + this.rawNode.filled = true; + return this; // self + }, + + setStroke: function(stroke){ + // summary: sets a stroke object (VML) + // stroke: Object: a stroke object + // (see dojox.gfx.defaultStroke) + + if(!stroke){ + // don't stroke + this.strokeStyle = null; + this.rawNode.stroked = "f"; + return this; + } + // normalize the stroke + if(typeof stroke == "string"){ + stroke = {color: stroke}; + } + var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke); + s.color = dojox.gfx.normalizeColor(s.color); + // generate attributes + var rn = this.rawNode; + rn.stroked = true; + rn.strokecolor = s.color.toCss(); + rn.strokeweight = s.width + "px"; // TODO: should we assume that the width is always in pixels? + if(rn.stroke) { + rn.stroke.opacity = s.color.a; + rn.stroke.endcap = this._translate(this._capMap, s.cap); + if(typeof s.join == "number") { + rn.stroke.joinstyle = "miter"; + rn.stroke.miterlimit = s.join; + }else{ + rn.stroke.joinstyle = s.join; + // rn.stroke.miterlimit = s.width; + } + rn.stroke.dashstyle = s.style == "none" ? "Solid" : s.style; + } + return this; // self + }, + + _capMap: { butt: 'flat' }, + _capMapReversed: { flat: 'butt' }, + + _translate: function(dict, value) { + return (value in dict) ? dict[value] : value; + }, + + _applyTransform: function() { + if(this.fillStyle && this.fillStyle.type == "linear"){ + this.setFill(this.fillStyle); + } + var matrix = this._getRealMatrix(); + if(!matrix) return this; + var skew = this.rawNode.skew; + if(typeof skew == "undefined"){ + for(var i = 0; i < this.rawNode.childNodes.length; ++i){ + if(this.rawNode.childNodes[i].tagName == "skew"){ + skew = this.rawNode.childNodes[i]; + break; + } + } + } + if(skew){ + skew.on = "f"; + var mt = matrix.xx.toFixed(8) + " " + matrix.xy.toFixed(8) + " " + + matrix.yx.toFixed(8) + " " + matrix.yy.toFixed(8) + " 0 0", + offset = Math.floor(matrix.dx).toFixed() + "px " + Math.floor(matrix.dy).toFixed() + "px", + s = this.rawNode.style, + l = parseFloat(s.left), + t = parseFloat(s.top), + w = parseFloat(s.width), + h = parseFloat(s.height); + if(isNaN(l)) l = 0; + if(isNaN(t)) t = 0; + if(isNaN(w)) w = 1; + if(isNaN(h)) h = 1; + var origin = (-l / w - 0.5).toFixed(8) + " " + (-t / h - 0.5).toFixed(8); + skew.matrix = mt; + skew.origin = origin; + skew.offset = offset; + skew.on = true; + } + return this; + }, + + setRawNode: function(rawNode){ + // summary: + // assigns and clears the underlying node that will represent this + // shape. Once set, transforms, gradients, etc, can be applied. + // (no fill & stroke by default) + rawNode.stroked = "f"; + rawNode.filled = "f"; + this.rawNode = rawNode; + }, + + // move family + + _moveToFront: function(){ + // summary: moves a shape to front of its parent's list of shapes (VML) + this.rawNode.parentNode.appendChild(this.rawNode); + return this; + }, + _moveToBack: function(){ + // summary: moves a shape to back of its parent's list of shapes (VML) + var r = this.rawNode, p = r.parentNode, n = p.firstChild; + p.insertBefore(r, n); + if(n.tagName == "rect"){ + // surface has a background rectangle, which position should be preserved + n.swapNode(r); + } + return this; + }, + + _getRealMatrix: function(){ + // summary: returns the cumulative ("real") transformation matrix + // by combining the shape's matrix with its parent's matrix + return this.parentMatrix ? new dojox.gfx.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix; // dojox.gfx.Matrix2D + } +}); + +dojo.declare("dojox.gfx.Group", dojox.gfx.Shape, { + // summary: a group shape (VML), which can be used + // to logically group shapes (e.g, to propagate matricies) + constructor: function(){ + dojox.gfx.vml.Container._init.call(this); + }, + // apply transformation + _applyTransform: function(){ + // summary: applies a transformation matrix to a group + var matrix = this._getRealMatrix(); + for(var i = 0; i < this.children.length; ++i){ + this.children[i]._updateParentMatrix(matrix); + } + return this; // self + } +}); +dojox.gfx.Group.nodeType = "group"; + +dojo.declare("dojox.gfx.Rect", dojox.gfx.shape.Rect, { + // summary: a rectangle shape (VML) + setShape: function(newShape){ + // summary: sets a rectangle shape object (VML) + // newShape: Object: a rectangle shape object + var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var style = this.rawNode.style; + style.left = shape.x.toFixed(); + style.top = shape.y.toFixed(); + style.width = (typeof shape.width == "string" && shape.width.indexOf("%") >= 0) ? shape.width : shape.width.toFixed(); + style.height = (typeof shape.width == "string" && shape.height.indexOf("%") >= 0) ? shape.height : shape.height.toFixed(); + var r = Math.min(1, (shape.r / Math.min(parseFloat(shape.width), parseFloat(shape.height)))).toFixed(8); + // a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node + var parent = this.rawNode.parentNode, before = null; + if(parent){ + if(parent.lastChild != this.rawNode){ + for(var i = 0; i < parent.childNodes.length; ++i){ + if(parent.childNodes[i] == this.rawNode){ + before = parent.childNodes[i+1]; + break; + } + } + } + parent.removeChild(this.rawNode); + } + this.rawNode.arcsize = r; + if(parent){ + if(before){ + parent.insertBefore(this.rawNode, before); + }else{ + parent.appendChild(this.rawNode); + } + } + // set all necessary styles, which are lost by VML (yes, it's a VML's bug) + return this.setTransform(this.matrix).setFill(this.fillStyle).setStroke(this.strokeStyle); // self + } +}); +dojox.gfx.Rect.nodeType = "roundrect"; // use a roundrect so the stroke join type is respected + +dojo.declare("dojox.gfx.Ellipse", dojox.gfx.shape.Ellipse, { + // summary: an ellipse shape (VML) + setShape: function(newShape){ + // summary: sets an ellipse shape object (VML) + // newShape: Object: an ellipse shape object + var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var style = this.rawNode.style; + style.left = (shape.cx - shape.rx).toFixed(); + style.top = (shape.cy - shape.ry).toFixed(); + style.width = (shape.rx * 2).toFixed(); + style.height = (shape.ry * 2).toFixed(); + return this.setTransform(this.matrix); // self + } +}); +dojox.gfx.Ellipse.nodeType = "oval"; + +dojo.declare("dojox.gfx.Circle", dojox.gfx.shape.Circle, { + // summary: a circle shape (VML) + setShape: function(newShape){ + // summary: sets a circle shape object (VML) + // newShape: Object: a circle shape object + var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var style = this.rawNode.style; + style.left = (shape.cx - shape.r).toFixed(); + style.top = (shape.cy - shape.r).toFixed(); + style.width = (shape.r * 2).toFixed(); + style.height = (shape.r * 2).toFixed(); + return this; // self + } +}); +dojox.gfx.Circle.nodeType = "oval"; + +dojo.declare("dojox.gfx.Line", dojox.gfx.shape.Line, { + // summary: a line shape (VML) + constructor: function(rawNode){ + if(rawNode) rawNode.setAttribute("dojoGfxType", "line"); + }, + setShape: function(newShape){ + // summary: sets a line shape object (VML) + // newShape: Object: a line shape object + var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + this.rawNode.path.v = "m" + shape.x1.toFixed() + " " + shape.y1.toFixed() + + "l" + shape.x2.toFixed() + " " + shape.y2.toFixed() + "e"; + return this.setTransform(this.matrix); // self + } +}); +dojox.gfx.Line.nodeType = "shape"; + +dojo.declare("dojox.gfx.Polyline", dojox.gfx.shape.Polyline, { + // summary: a polyline/polygon shape (VML) + constructor: function(rawNode){ + if(rawNode) rawNode.setAttribute("dojoGfxType", "polyline"); + }, + setShape: function(points, closed){ + // summary: sets a polyline/polygon shape object (VML) + // points: Object: a polyline/polygon shape object + // closed: Boolean?: if true, close the polyline explicitely + if(points && points instanceof Array){ + // branch + // points: Array: an array of points + this.shape = dojox.gfx.makeParameters(this.shape, { points: points }); + if(closed && this.shape.points.length) this.shape.points.push(this.shape.points[0]); + }else{ + this.shape = dojox.gfx.makeParameters(this.shape, points); + } + this.bbox = null; + var attr = [], p = this.shape.points; + if(p.length > 0){ + attr.push("m"); + var k = 1; + if(typeof p[0] == "number"){ + attr.push(p[0].toFixed()); + attr.push(p[1].toFixed()); + k = 2; + }else{ + attr.push(p[0].x.toFixed()); + attr.push(p[0].y.toFixed()); + } + if(p.length > k){ + attr.push("l"); + for(var i = k; i < p.length; ++i){ + if(typeof p[i] == "number"){ + attr.push(p[i].toFixed()); + }else{ + attr.push(p[i].x.toFixed()); + attr.push(p[i].y.toFixed()); + } + } + } + } + attr.push("e"); + this.rawNode.path.v = attr.join(" "); + return this.setTransform(this.matrix); // self + } +}); +dojox.gfx.Polyline.nodeType = "shape"; + +dojo.declare("dojox.gfx.Image", dojox.gfx.shape.Image, { + // summary: an image (VML) + constructor: function(rawNode){ + if(rawNode) rawNode.setAttribute("dojoGfxType", "image"); + }, + getEventSource: function() { + // summary: returns a Node, which is used as + // a source of events for this shape + return this.rawNode ? this.rawNode.firstChild : null; // Node + }, + setShape: function(newShape){ + // summary: sets an image shape object (VML) + // newShape: Object: an image shape object + var shape = this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + this.rawNode.firstChild.src = shape.src; + return this.setTransform(this.matrix); // self + }, + _setDimensions: function(s, w, h){ + if(w || h){ + s.width = w + "px"; + s.height = h + "px"; + } + }, + _resetImage: function(){ + var s = this.rawNode.firstChild.style, + shape = this.shape; + s.left = "0px"; + s.top = "0px"; + this._setDimensions(s, shape.width, shape.height); + }, + _applyTransform: function() { + var matrix = this._getRealMatrix(), + img = this.rawNode.firstChild, + s = img.style, + shape = this.shape; + if(matrix){ + matrix = dojox.gfx.matrix.multiply(matrix, {dx: shape.x, dy: shape.y}); + }else{ + matrix = dojox.gfx.matrix.normalize({dx: shape.x, dy: shape.y}); + } + if(matrix.xy == 0 && matrix.yx == 0 && matrix.xx > 0 && matrix.yy > 0){ + // special case to avoid filters + this.rawNode.style.filter = ""; + s.left = Math.floor(matrix.dx) + "px"; + s.top = Math.floor(matrix.dy) + "px"; + this._setDimensions(s, Math.floor(matrix.xx * shape.width), Math.floor(matrix.yy * shape.height)); + }else{ + this._resetImage(); + var f = this.rawNode.filters["DXImageTransform.Microsoft.Matrix"]; + if(f){ + f.M11 = matrix.xx; + f.M12 = matrix.xy; + f.M21 = matrix.yx; + f.M22 = matrix.yy; + f.Dx = matrix.dx; + f.Dy = matrix.dy; + }else{ + this.rawNode.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11=" + matrix.xx + + ", M12=" + matrix.xy + ", M21=" + matrix.yx + ", M22=" + matrix.yy + + ", Dx=" + matrix.dx + ", Dy=" + matrix.dy + ")"; + } + } + return this; + } +}); +dojox.gfx.Image.nodeType = "div"; + +dojo.declare("dojox.gfx.Text", dojox.gfx.shape.Text, { + // summary: an anchored text (VML) + constructor: function(rawNode){ + if(rawNode){rawNode.setAttribute("dojoGfxType", "text");} + this.fontStyle = null; + }, + _alignment: {start: "left", middle: "center", end: "right"}, + setShape: function(newShape){ + // summary: sets a text shape object (VML) + // newShape: Object: a text shape object + this.shape = dojox.gfx.makeParameters(this.shape, newShape); + this.bbox = null; + var r = this.rawNode, s = this.shape, x = s.x, y = s.y.toFixed(); + switch(s.align){ + case "middle": + x -= 5; + break; + case "end": + x -= 10; + break; + } + this.rawNode.path.v = "m" + x.toFixed() + "," + y + + "l" + (x + 10).toFixed() + "," + y + "e"; + // find path and text path + var p = null, t = null, c = r.childNodes; + for(var i = 0; i < c.length; ++i){ + var tag = c[i].tagName; + if(tag == "path"){ + p = c[i]; + if(t) break; + }else if(tag == "textpath"){ + t = c[i]; + if(p) break; + } + } + if(!p){ + p = this.rawNode.ownerDocument.createElement("v:path"); + r.appendChild(p); + } + if(!t){ + t = this.rawNode.ownerDocument.createElement("v:textpath"); + r.appendChild(t); + } + p.textPathOk = true; + t.on = true; + var a = dojox.gfx.vml.text_alignment[s.align]; + t.style["v-text-align"] = a ? a : "left"; + t.style["text-decoration"] = s.decoration; + t.style["v-rotate-letters"] = s.rotated; + t.style["v-text-kern"] = s.kerning; + t.string = s.text; + return this.setTransform(this.matrix); // self + }, + _setFont: function(){ + // summary: sets a font object (VML) + var f = this.fontStyle, c = this.rawNode.childNodes; + for(var i = 0; i < c.length; ++i){ + if(c[i].tagName == "textpath"){ + c[i].style.font = dojox.gfx.makeFontString(f); + break; + } + } + this.setTransform(this.matrix); + }, + _getRealMatrix: function(){ + // summary: returns the cumulative ("real") transformation matrix + // by combining the shape's matrix with its parent's matrix; + // it makes a correction for a font size + var matrix = dojox.gfx.Shape.prototype._getRealMatrix.call(this); + // It appears that text is always aligned vertically at a middle of x-height (???). + // It is impossible to obtain these metrics from VML => I try to approximate it with + // more-or-less util value of 0.7 * FontSize, which is typical for European fonts. + if(matrix){ + matrix = dojox.gfx.matrix.multiply(matrix, + {dy: -dojox.gfx.normalizedLength(this.fontStyle ? this.fontStyle.size : "10pt") * 0.35}); + } + return matrix; // dojox.gfx.Matrix2D + }, + getTextWidth: function(){ + // summary: get the text width, in px + var rawNode = this.rawNode, _display = rawNode.style.display; + rawNode.style.display = "inline"; + var _width = dojox.gfx.pt2px(parseFloat(rawNode.currentStyle.width)); + rawNode.style.display = _display; + return _width; + } +}); +dojox.gfx.Text.nodeType = "shape"; + +dojox.gfx.path._calcArc = function(alpha){ + // return a start point, 1st and 2nd control points, and an end point + var cosa = Math.cos(alpha), sina = Math.sin(alpha), + p2 = {x: cosa + (4 / 3) * (1 - cosa), y: sina - (4 / 3) * cosa * (1 - cosa) / sina}; + return { + s: {x: cosa, y: -sina}, + c1: {x: p2.x, y: -p2.y}, + c2: p2, + e: {x: cosa, y: sina} + }; +}; + +dojo.declare("dojox.gfx.Path", dojox.gfx.path.Path, { + // summary: a path shape (VML) + constructor: function(rawNode){ + if(rawNode && !rawNode.getAttribute("dojoGfxType")){ + rawNode.setAttribute("dojoGfxType", "path"); + } + this.vmlPath = ""; + this.lastControl = {}; + }, + _updateWithSegment: function(segment){ + // summary: updates the bounding box of path with new segment + // segment: Object: a segment + var last = dojo.clone(this.last); + dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments); + // add a VML path segment + var path = this[this.renderers[segment.action]](segment, last); + if(typeof this.vmlPath == "string"){ + this.vmlPath += path.join(""); + this.rawNode.path.v = this.vmlPath + " r0,0 e"; + }else{ + this.vmlPath = this.vmlPath.concat(path); + } + }, + setShape: function(newShape){ + // summary: forms a path using a shape (VML) + // newShape: Object: an VML path string or a path object (see dojox.gfx.defaultPath) + this.vmlPath = []; + this.lastControl = {}; + dojox.gfx.Path.superclass.setShape.apply(this, arguments); + this.vmlPath = this.vmlPath.join(""); + this.rawNode.path.v = this.vmlPath + " r0,0 e"; + return this; + }, + _pathVmlToSvgMap: {m: "M", l: "L", t: "m", r: "l", c: "C", v: "c", qb: "Q", x: "z", e: ""}, + // VML-specific segment renderers + renderers: { + M: "_moveToA", m: "_moveToR", + L: "_lineToA", l: "_lineToR", + H: "_hLineToA", h: "_hLineToR", + V: "_vLineToA", v: "_vLineToR", + C: "_curveToA", c: "_curveToR", + S: "_smoothCurveToA", s: "_smoothCurveToR", + Q: "_qCurveToA", q: "_qCurveToR", + T: "_qSmoothCurveToA", t: "_qSmoothCurveToR", + A: "_arcTo", a: "_arcTo", + Z: "_closePath", z: "_closePath" + }, + _addArgs: function(path, args, from, upto){ + if(typeof upto == "undefined"){ + upto = args.length; + } + if(typeof from == "undefined"){ + from = 0; + } + for(var i = from; i < upto; ++i){ + path.push(" "); + path.push(args[i].toFixed()); + } + }, + _addArgsAdjusted: function(path, last, args, from, upto){ + if(typeof upto == "undefined"){ + upto = args.length; + } + if(typeof from == "undefined"){ + from = 0; + } + for(var i = from; i < upto; i += 2){ + path.push(" "); + path.push((last.x + args[i]).toFixed()); + path.push(" "); + path.push((last.y + args[i + 1]).toFixed()); + } + }, + _moveToA: function(segment){ + var p = [" m"], n = segment.args, l = n.length; + if(l == 2){ + this._addArgs(p, n); + }else{ + this._addArgs(p, n, 0, 2); + p.push(" l"); + this._addArgs(p, n, 2); + } + this.lastControl = {}; + return p; + }, + _moveToR: function(segment, last){ + var p = ["x" in last ? " t" : " m"], n = segment.args, l = n.length; + if(l == 2){ + this._addArgs(p, n); + }else{ + this._addArgs(p, n, 0, 2); + p.push(" r"); + this._addArgs(p, n, 2); + } + this.lastControl = {}; + return p; + }, + _lineToA: function(segment){ + var p = [" l"]; + this._addArgs(p, segment.args); + this.lastControl = {}; + return p; + }, + _lineToR: function(segment){ + var p = [" r"]; + this._addArgs(p, segment.args); + this.lastControl = {}; + return p; + }, + _hLineToA: function(segment, last){ + var p = [" l"], n = segment.args, l = n.length, y = " " + last.y.toFixed(); + for(var i = 0; i < l; ++i){ + p.push(" "); + p.push(n[i].toFixed()); + p.push(y); + } + this.lastControl = {}; + return p; + }, + _hLineToR: function(segment){ + var p = [" r"], n = segment.args, l = n.length; + for(var i = 0; i < l; ++i){ + p.push(" "); + p.push(n[i].toFixed()); + p.push(" 0"); + } + this.lastControl = {}; + return p; + }, + _vLineToA: function(segment, last){ + var p = [" l"], n = segment.args, l = n.length, x = " " + last.x.toFixed(); + for(var i = 0; i < l; ++i){ + p.push(x); + p.push(" "); + p.push(n[i].toFixed()); + } + this.lastControl = {}; + return p; + }, + _vLineToR: function(segment){ + var p = [" r"], n = segment.args, l = n.length; + for(var i = 0; i < l; ++i){ + p.push(" 0 "); + p.push(n[i].toFixed()); + } + this.lastControl = {}; + return p; + }, + _curveToA: function(segment){ + var p = [], n = segment.args, l = n.length; + for(var i = 0; i < l; i += 6){ + p.push(" c"); + this._addArgs(p, n, i, i + 6); + } + this.lastControl = {x: n[l - 4], y: n[l - 3], type: "C"}; + return p; + }, + _curveToR: function(segment, last){ + var p = [], n = segment.args, l = n.length; + for(var i = 0; i < l; i += 6){ + p.push(" v"); + this._addArgs(p, n, i, i + 6); + this.lastControl = {x: last.x + n[i + 2], y: last.y + n[i + 3]}; + last.x += n[i + 4]; + last.y += n[i + 5]; + } + this.lastControl.type = "C"; + return p; + }, + _smoothCurveToA: function(segment, last){ + var p = [], n = segment.args, l = n.length; + for(var i = 0; i < l; i += 4){ + p.push(" c"); + if(this.lastControl.type == "C"){ + this._addArgs(p, [ + 2 * last.x - this.lastControl.x, + 2 * last.y - this.lastControl.y + ]); + }else{ + this._addArgs(p, [last.x, last.y]); + } + this._addArgs(p, n, i, i + 4); + } + this.lastControl = {x: n[l - 4], y: n[l - 3], type: "C"}; + return p; + }, + _smoothCurveToR: function(segment, last){ + var p = [], n = segment.args, l = n.length; + for(var i = 0; i < l; i += 4){ + p.push(" v"); + if(this.lastControl.type == "C"){ + this._addArgs(p, [ + last.x - this.lastControl.x, + last.y - this.lastControl.y + ]); + }else{ + this._addArgs(p, [0, 0]); + } + this._addArgs(p, n, i, i + 4); + this.lastControl = {x: last.x + n[i], y: last.y + n[i + 1]}; + last.x += n[i + 2]; + last.y += n[i + 3]; + } + this.lastControl.type = "C"; + return p; + }, + _qCurveToA: function(segment){ + var p = [], n = segment.args, l = n.length; + for(var i = 0; i < l; i += 4){ + p.push(" qb"); + this._addArgs(p, n, i, i + 4); + } + this.lastControl = {x: n[l - 4], y: n[l - 3], type: "Q"}; + return p; + }, + _qCurveToR: function(segment, last){ + var p = [], n = segment.args, l = n.length; + for(var i = 0; i < l; i += 4){ + p.push(" qb"); + this._addArgsAdjusted(p, last, n, i, i + 4); + this.lastControl = {x: last.x + n[i], y: last.y + n[i + 1]}; + last.x += n[i + 2]; + last.y += n[i + 3]; + } + this.lastControl.type = "Q"; + return p; + }, + _qSmoothCurveToA: function(segment, last){ + var p = [], n = segment.args, l = n.length; + for(var i = 0; i < l; i += 2){ + p.push(" qb"); + if(this.lastControl.type == "Q"){ + this._addArgs(p, [ + this.lastControl.x = 2 * last.x - this.lastControl.x, + this.lastControl.y = 2 * last.y - this.lastControl.y + ]); + }else{ + this._addArgs(p, [ + this.lastControl.x = last.x, + this.lastControl.y = last.y + ]); + } + this._addArgs(p, n, i, i + 2); + } + this.lastControl.type = "Q"; + return p; + }, + _qSmoothCurveToR: function(segment, last){ + var p = [], n = segment.args, l = n.length; + for(var i = 0; i < l; i += 2){ + p.push(" qb"); + if(this.lastControl.type == "Q"){ + this._addArgs(p, [ + this.lastControl.x = 2 * last.x - this.lastControl.x, + this.lastControl.y = 2 * last.y - this.lastControl.y + ]); + }else{ + this._addArgs(p, [ + this.lastControl.x = last.x, + this.lastControl.y = last.y + ]); + } + this._addArgsAdjusted(p, last, n, i, i + 2); + } + this.lastControl.type = "Q"; + return p; + }, + _arcTo: function(segment, last){ + var p = [], n = segment.args, l = n.length, relative = segment.action == "a"; + for(var i = 0; i < l; i += 7){ + var x1 = n[i + 5], y1 = n[i + 6]; + if(relative){ + x1 += last.x; + y1 += last.y; + } + var result = dojox.gfx.arc.arcAsBezier( + last, n[i], n[i + 1], n[i + 2], + n[i + 3] ? 1 : 0, n[i + 4] ? 1 : 0, + x1, y1 + ); + for(var j = 0; j < result.length; ++j){ + p.push(" c"); + this._addArgs(p, result[j]); + } + last = {x: x1, y: y1}; + } + this.lastControl = {}; + return p; + }, + _closePath: function(){ + this.lastControl = {}; + return ["x"]; + } +}); +dojox.gfx.Path.nodeType = "shape"; + +dojo.declare("dojox.gfx.TextPath", dojox.gfx.Path, { + // summary: a textpath shape (VML) + constructor: function(rawNode){ + if(rawNode){rawNode.setAttribute("dojoGfxType", "textpath");} + this.fontStyle = null; + if(!("text" in this)){ + this.text = dojo.clone(dojox.gfx.defaultTextPath); + } + if(!("fontStyle" in this)){ + this.fontStyle = dojo.clone(dojox.gfx.defaultFont); + } + }, + setText: function(newText){ + // summary: sets a text to be drawn along the path + this.text = dojox.gfx.makeParameters(this.text, + typeof newText == "string" ? {text: newText} : newText); + this._setText(); + return this; // self + }, + setFont: function(newFont){ + // summary: sets a font for text + this.fontStyle = typeof newFont == "string" ? + dojox.gfx.splitFontString(newFont) : + dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont); + this._setFont(); + return this; // self + }, + + _setText: function(){ + // summary: sets a text shape object (VML) + this.bbox = null; + var r = this.rawNode, s = this.text, + // find path and text path + p = null, t = null, c = r.childNodes; + for(var i = 0; i < c.length; ++i){ + var tag = c[i].tagName; + if(tag == "path"){ + p = c[i]; + if(t) break; + }else if(tag == "textpath"){ + t = c[i]; + if(p) break; + } + } + if(!p){ + p = this.rawNode.ownerDocument.createElement("v:path"); + r.appendChild(p); + } + if(!t){ + t = this.rawNode.ownerDocument.createElement("v:textpath"); + r.appendChild(t); + } + p.textPathOk = true; + t.on = true; + var a = dojox.gfx.vml.text_alignment[s.align]; + t.style["v-text-align"] = a ? a : "left"; + t.style["text-decoration"] = s.decoration; + t.style["v-rotate-letters"] = s.rotated; + t.style["v-text-kern"] = s.kerning; + t.string = s.text; + }, + _setFont: function(){ + // summary: sets a font object (VML) + var f = this.fontStyle, c = this.rawNode.childNodes; + for(var i = 0; i < c.length; ++i){ + if(c[i].tagName == "textpath"){ + c[i].style.font = dojox.gfx.makeFontString(f); + break; + } + } + } +}); +dojox.gfx.TextPath.nodeType = "shape"; + +dojo.declare("dojox.gfx.Surface", dojox.gfx.shape.Surface, { + // summary: a surface object to be used for drawings (VML) + constructor: function(){ + dojox.gfx.vml.Container._init.call(this); + }, + setDimensions: function(width, height){ + // summary: sets the width and height of the rawNode + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + this.width = dojox.gfx.normalizedLength(width); // in pixels + this.height = dojox.gfx.normalizedLength(height); // in pixels + if(!this.rawNode) return this; + var cs = this.clipNode.style, + r = this.rawNode, rs = r.style, + bs = this.bgNode.style; + cs.width = width; + cs.height = height; + cs.clip = "rect(0 " + width + " " + height + " 0)"; + rs.width = width; + rs.height = height; + r.coordsize = width + " " + height; + bs.width = width; + bs.height = height; + return this; // self + }, + getDimensions: function(){ + // summary: returns an object with properties "width" and "height" + var t = this.rawNode ? { + width: dojox.gfx.normalizedLength(this.rawNode.style.width), + height: dojox.gfx.normalizedLength(this.rawNode.style.height)} : null; + if(t.width <= 0){ t.width = this.width; } + if(t.height <= 0){ t.height = this.height; } + return t; // Object + } +}); + +dojox.gfx.createSurface = function(parentNode, width, height){ + // summary: creates a surface (VML) + // parentNode: Node: a parent node + // width: String: width of surface, e.g., "100px" + // height: String: height of surface, e.g., "100px" + + if(!width){ width = "100%"; } + if(!height){ height = "100%"; } + var s = new dojox.gfx.Surface(), p = dojo.byId(parentNode), + c = s.clipNode = p.ownerDocument.createElement("div"), + r = s.rawNode = p.ownerDocument.createElement("v:group"), + cs = c.style, rs = r.style; + + p.style.width = width; + p.style.height = height; + + cs.position = "absolute"; + cs.width = width; + cs.height = height; + cs.clip = "rect(0 " + width + " " + height + " 0)"; + rs.position = "absolute"; + rs.width = width; + rs.height = height; + r.coordsize = (width == "100%" ? width : parseFloat(width)) + " " + + (height == "100%" ? height : parseFloat(height)); + r.coordorigin = "0 0"; + + // create a background rectangle, which is required to show all other shapes + var b = s.bgNode = r.ownerDocument.createElement("v:rect"), bs = b.style; + bs.left = bs.top = 0; + bs.width = rs.width; + bs.height = rs.height; + b.filled = b.stroked = "f"; + + r.appendChild(b); + c.appendChild(r); + p.appendChild(c); + + s.width = dojox.gfx.normalizedLength(width); // in pixels + s.height = dojox.gfx.normalizedLength(height); // in pixels + + return s; // dojox.gfx.Surface +}; + +// Extenders + +dojox.gfx.vml.Container = { + _init: function(){ + dojox.gfx.shape.Container._init.call(this); + }, + add: function(shape){ + // summary: adds a shape to a group/surface + // shape: dojox.gfx.Shape: an VML shape object + if(this != shape.getParent()){ + this.rawNode.appendChild(shape.rawNode); + //dojox.gfx.Group.superclass.add.apply(this, arguments); + //this.inherited(arguments); + dojox.gfx.shape.Container.add.apply(this, arguments); + } + return this; // self + }, + remove: function(shape, silently){ + // summary: remove a shape from a group/surface + // shape: dojox.gfx.Shape: an VML shape object + // silently: Boolean?: if true, regenerate a picture + if(this == shape.getParent()){ + if(this.rawNode == shape.rawNode.parentNode){ + this.rawNode.removeChild(shape.rawNode); + } + //dojox.gfx.Group.superclass.remove.apply(this, arguments); + //this.inherited(arguments); + dojox.gfx.shape.Container.remove.apply(this, arguments); + } + return this; // self + }, + clear: function(){ + // summary: removes all shapes from a group/surface + var r = this.rawNode; + while(r.firstChild != r.lastChild){ + if(r.firstChild != this.bgNode){ + r.removeChild(r.firstChild); + } + if(r.lastChild != this.bgNode){ + r.removeChild(r.lastChild); + } + } + //return this.inherited(arguments); // self + return dojox.gfx.shape.Container.clear.apply(this, arguments); + }, + _moveChildToFront: dojox.gfx.shape.Container._moveChildToFront, + _moveChildToBack: dojox.gfx.shape.Container._moveChildToBack +}; + +dojo.mixin(dojox.gfx.shape.Creator, { + // summary: VML shape creators + createGroup: function(){ + // summary: creates a VML group shape + var g = this.createObject(dojox.gfx.Group, null); // dojox.gfx.Group + // create a background rectangle, which is required to show all other shapes + var r = g.rawNode.ownerDocument.createElement("v:rect"); + r.style.left = r.style.top = 0; + r.style.width = g.rawNode.style.width; + r.style.height = g.rawNode.style.height; + r.filled = r.stroked = "f"; + g.rawNode.appendChild(r); + g.bgNode = r; + return g; // dojox.gfx.Group + }, + createImage: function(image){ + // summary: creates a VML image shape + // image: Object: an image object (see dojox.gfx.defaultImage) + if(!this.rawNode) return null; + var shape = new dojox.gfx.Image(), node = this.rawNode.ownerDocument.createElement('div'); + node.style.position = "absolute"; + node.style.width = this.rawNode.style.width; + node.style.height = this.rawNode.style.height; + //node.style.filter = "progid:DXImageTransform.Microsoft.Matrix(M11=1, M12=0, M21=0, M22=1, Dx=0, Dy=0)"; + var img = this.rawNode.ownerDocument.createElement('img'); + img.style.position = "relative"; + node.appendChild(img); + shape.setRawNode(node); + this.rawNode.appendChild(node); + shape.setShape(image); + this.add(shape); + return shape; // dojox.gfx.Image + }, + createObject: function(shapeType, rawShape) { + // summary: creates an instance of the passed shapeType class + // shapeType: Function: a class constructor to create an instance of + // rawShape: Object: properties to be passed in to the classes "setShape" method + // overrideSize: Boolean: set the size explicitly, if true + if(!this.rawNode) return null; + var shape = new shapeType(), + node = this.rawNode.ownerDocument.createElement('v:' + shapeType.nodeType); + shape.setRawNode(node); + this.rawNode.appendChild(node); + switch(shapeType){ + case dojox.gfx.Group: + case dojox.gfx.Line: + case dojox.gfx.Polyline: + case dojox.gfx.Text: + case dojox.gfx.Path: + case dojox.gfx.TextPath: + this._overrideSize(node); + } + shape.setShape(rawShape); + this.add(shape); + return shape; // dojox.gfx.Shape + }, + _overrideSize: function(node){ + var p = this; + while(p && !(p instanceof dojox.gfx.Surface)){ p = p.parent; } + node.style.width = p.width; + node.style.height = p.height; + node.coordsize = p.width + " " + p.height; + } +}); + +dojo.extend(dojox.gfx.Group, dojox.gfx.vml.Container); +dojo.extend(dojox.gfx.Group, dojox.gfx.shape.Creator); + +dojo.extend(dojox.gfx.Surface, dojox.gfx.vml.Container); +dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator); + +} diff --git a/includes/js/dojox/gfx/vml_attach.js b/includes/js/dojox/gfx/vml_attach.js new file mode 100644 index 0000000..b54d31b --- /dev/null +++ b/includes/js/dojox/gfx/vml_attach.js @@ -0,0 +1,362 @@ +dojo.require("dojox.gfx.vml"); + +dojo.experimental("dojox.gfx.vml_attach"); + +(function(){ + dojox.gfx.attachNode = function(node){ + // summary: creates a shape from a Node + // node: Node: an VML node + if(!node) return null; + var s = null; + switch(node.tagName.toLowerCase()){ + case dojox.gfx.Rect.nodeType: + s = new dojox.gfx.Rect(node); + attachRect(s); + break; + case dojox.gfx.Ellipse.nodeType: + if(node.style.width == node.style.height){ + s = new dojox.gfx.Circle(node); + attachCircle(s); + }else{ + s = new dojox.gfx.Ellipse(node); + attachEllipse(s); + } + break; + case dojox.gfx.Path.nodeType: + switch(node.getAttribute("dojoGfxType")){ + case "line": + s = new dojox.gfx.Line(node); + attachLine(s); + break; + case "polyline": + s = new dojox.gfx.Polyline(node); + attachPolyline(s); + break; + case "path": + s = new dojox.gfx.Path(node); + attachPath(s); + break; + case "text": + s = new dojox.gfx.Text(node); + attachText(s); + attachFont(s); + attachTextTransform(s); + break; + case "textpath": + s = new dojox.gfx.TextPath(node); + attachPath(s); + attachText(s); + attachFont(s); + break; + } + break; + case dojox.gfx.Image.nodeType: + switch(node.getAttribute("dojoGfxType")){ + case "image": + s = new dojox.gfx.Image(node); + attachImage(s); + attachImageTransform(s); + break; + } + break; + default: + //console.debug("FATAL ERROR! tagName = " + node.tagName); + return null; + } + if(!(s instanceof dojox.gfx.Image)){ + attachFill(s); + attachStroke(s); + if(!(s instanceof dojox.gfx.Text)){ + attachTransform(s); + } + } + return s; // dojox.gfx.Shape + }; + + dojox.gfx.attachSurface = function(node){ + // summary: creates a surface from a Node + // node: Node: an VML node + var s = new dojox.gfx.Surface(); + s.clipNode = node; + var r = s.rawNode = node.firstChild; + var b = r.firstChild; + if(!b || b.tagName != "rect"){ + return null; // dojox.gfx.Surface + } + s.bgNode = r; + return s; // dojox.gfx.Surface + }; + + var attachFill = function(object){ + // summary: deduces a fill style from a node. + // object: dojox.gfx.Shape: an VML shape + var fillStyle = null, r = object.rawNode, fo = r.fill; + if(fo.on && fo.type == "gradient"){ + var fillStyle = dojo.clone(dojox.gfx.defaultLinearGradient), + rad = dojox.gfx.matrix._degToRad(fo.angle); + fillStyle.x2 = Math.cos(rad); + fillStyle.y2 = Math.sin(rad); + fillStyle.colors = []; + var stops = fo.colors.value.split(";"); + for(var i = 0; i < stops.length; ++i){ + var t = stops[i].match(/\S+/g); + if(!t || t.length != 2){ continue; } + fillStyle.colors.push({offset: dojox.gfx.vml._parseFloat(t[0]), color: new dojo.Color(t[1])}); + } + }else if(fo.on && fo.type == "gradientradial"){ + var fillStyle = dojo.clone(dojox.gfx.defaultRadialGradient), + w = parseFloat(r.style.width), h = parseFloat(r.style.height); + fillStyle.cx = isNaN(w) ? 0 : fo.focusposition.x * w; + fillStyle.cy = isNaN(h) ? 0 : fo.focusposition.y * h; + fillStyle.r = isNaN(w) ? 1 : w / 2; + fillStyle.colors = []; + var stops = fo.colors.value.split(";"); + for(var i = stops.length - 1; i >= 0; --i){ + var t = stops[i].match(/\S+/g); + if(!t || t.length != 2){ continue; } + fillStyle.colors.push({offset: dojox.gfx.vml._parseFloat(t[0]), color: new dojo.Color(t[1])}); + } + }else if(fo.on && fo.type == "tile"){ + var fillStyle = dojo.clone(dojox.gfx.defaultPattern); + fillStyle.width = dojox.gfx.pt2px(fo.size.x); // from pt + fillStyle.height = dojox.gfx.pt2px(fo.size.y); // from pt + fillStyle.x = fo.origin.x * fillStyle.width; + fillStyle.y = fo.origin.y * fillStyle.height; + fillStyle.src = fo.src; + }else if(fo.on && r.fillcolor){ + // a color object ! + fillStyle = new dojo.Color(r.fillcolor+""); + fillStyle.a = fo.opacity; + } + object.fillStyle = fillStyle; + }; + + var attachStroke = function(object) { + // summary: deduces a stroke style from a node. + // object: dojox.gfx.Shape: an VML shape + var r = object.rawNode; + if(!r.stroked){ + object.strokeStyle = null; + return; + } + var strokeStyle = object.strokeStyle = dojo.clone(dojox.gfx.defaultStroke), + rs = r.stroke; + strokeStyle.color = new dojo.Color(r.strokecolor.value); + strokeStyle.width = dojox.gfx.normalizedLength(r.strokeweight+""); + strokeStyle.color.a = rs.opacity; + strokeStyle.cap = this._translate(this._capMapReversed, rs.endcap); + strokeStyle.join = rs.joinstyle == "miter" ? rs.miterlimit : rs.joinstyle; + strokeStyle.style = rs.dashstyle; + }; + + var attachTransform = function(object) { + // summary: deduces a transformation matrix from a node. + // object: dojox.gfx.Shape: an VML shape + var s = rawNode.skew, sm = s.matrix, so = s.offset; + object.matrix = dojox.gfx.matrix.normalize({ + xx: sm.xtox, + xy: sm.ytox, + yx: sm.xtoy, + yy: sm.ytoy, + dx: dojox.gfx.pt2px(so.x), + dy: dojox.gfx.pt2px(so.y) + }); + }; + + var attachGroup = function(object){ + // summary: reconstructs all group shape parameters from a node (VML). + // object: dojox.gfx.Shape: an VML shape + // attach the background + object.bgNode = object.rawNode.firstChild; // TODO: check it first + }; + + var attachRect = function(object){ + // summary: builds a rectangle shape from a node. + // object: dojox.gfx.Shape: an VML shape + // a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node + var r = object.rawNode, arcsize = r.outerHTML.match(/arcsize = \"(\d*\.?\d+[%f]?)\"/)[1], + style = r.style, width = parseFloat(style.width), height = parseFloat(style.height); + arcsize = (arcsize.indexOf("%") >= 0) ? parseFloat(arcsize) / 100 : dojox.gfx.vml._parseFloat(arcsize); + // make an object + object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultRect, { + x: parseInt(style.left), + y: parseInt(style.top), + width: width, + height: height, + r: Math.min(width, height) * arcsize + }); + }; + + var attachEllipse = function(object){ + // summary: builds an ellipse shape from a node. + // object: dojox.gfx.Shape: an VML shape + var style = object.rawNode.style, + rx = parseInt(style.width ) / 2, + ry = parseInt(style.height) / 2; + object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultEllipse, { + cx: parseInt(style.left) + rx, + cy: parseInt(style.top ) + ry, + rx: rx, + ry: ry + }); + }; + + var attachCircle = function(object){ + // summary: builds a circle shape from a node. + // object: dojox.gfx.Shape: an VML shape + var style = object.rawNode.style, r = parseInt(style.width) / 2; + object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultCircle, { + cx: parseInt(style.left) + r, + cy: parseInt(style.top) + r, + r: r + }); + }; + + var attachLine = function(object){ + // summary: builds a line shape from a node. + // object: dojox.gfx.Shape: an VML shape + var shape = object.shape = dojo.clone(dojox.gfx.defaultLine), + p = object.rawNode.path.v.match(dojox.gfx.pathVmlRegExp); + do{ + if(p.length < 7 || p[0] != "m" || p[3] != "l" || p[6] != "e"){ break; } + shape.x1 = parseInt(p[1]); + shape.y1 = parseInt(p[2]); + shape.x2 = parseInt(p[4]); + shape.y2 = parseInt(p[5]); + }while(false); + }; + + var attachPolyline = function(object){ + // summary: builds a polyline/polygon shape from a node. + // object: dojox.gfx.Shape: an VML shape + var shape = object.shape = dojo.clone(dojox.gfx.defaultPolyline), + p = object.rawNode.path.v.match(dojox.gfx.pathVmlRegExp); + do{ + if(p.length < 3 || p[0] != "m"){ break; } + var x = parseInt(p[0]), y = parseInt(p[1]); + if(isNaN(x) || isNaN(y)){ break; } + shape.points.push({x: x, y: y}); + if(p.length < 6 || p[3] != "l"){ break; } + for(var i = 4; i < p.length; i += 2){ + x = parseInt(p[i]); + y = parseInt(p[i + 1]); + if(isNaN(x) || isNaN(y)){ break; } + shape.points.push({x: x, y: y}); + } + }while(false); + }; + + var attachImage = function(object){ + // summary: builds an image shape from a node. + // object: dojox.gfx.Shape: an VML shape + object.shape = dojo.clone(dojox.gfx.defaultImage); + object.shape.src = object.rawNode.firstChild.src; + }; + + var attachImageTransform = function(object) { + // summary: deduces a transformation matrix from a node. + // object: dojox.gfx.Shape: an VML shape + var m = object.rawNode.filters["DXImageTransform.Microsoft.Matrix"]; + object.matrix = dojox.gfx.matrix.normalize({ + xx: m.M11, + xy: m.M12, + yx: m.M21, + yy: m.M22, + dx: m.Dx, + dy: m.Dy + }); + }; + + var attachText = function(object){ + // summary: builds a text shape from a node. + // object: dojox.gfx.Shape: an VML shape + var shape = object.shape = dojo.clone(dojox.gfx.defaultText), + r = object.rawNode, p = r.path.v.match(dojox.gfx.pathVmlRegExp); + do{ + if(!p || p.length != 7){ break; } + var c = r.childNodes, i = 0; + for(; i < c.length && c[i].tagName != "textpath"; ++i); + if(i >= c.length){ break; } + var s = c[i].style; + shape.text = c[i].string; + switch(s["v-text-align"]){ + case "left": + shape.x = parseInt(p[1]); + shape.align = "start"; + break; + case "center": + shape.x = (parseInt(p[1]) + parseInt(p[4])) / 2; + shape.align = "middle"; + break; + case "right": + shape.x = parseInt(p[4]); + shape.align = "end"; + break; + } + shape.y = parseInt(p[2]); + shape.decoration = s["text-decoration"]; + shape.rotated = s["v-rotate-letters"].toLowerCase() in dojox.gfx.vml._bool; + shape.kerning = s["v-text-kern"].toLowerCase() in dojox.gfx.vml._bool; + return; + }while(false); + object.shape = null; + }; + + var attachFont = function(object){ + // summary: deduces a font style from a node. + // object: dojox.gfx.Shape: an VML shape + var fontStyle = object.fontStyle = dojo.clone(dojox.gfx.defaultFont), + c = object.rawNode.childNodes, i = 0; + for(; i < c.length && c[i].tagName == "textpath"; ++i); + if(i >= c.length){ + object.fontStyle = null; + return; + } + var s = c[i].style; + fontStyle.style = s.fontstyle; + fontStyle.variant = s.fontvariant; + fontStyle.weight = s.fontweight; + fontStyle.size = s.fontsize; + fontStyle.family = s.fontfamily; + }; + + var attachTextTransform = function(object) { + // summary: deduces a transformation matrix from a node. + // object: dojox.gfx.Shape: an VML shape + attachTransform(object); + var matrix = object.matrix, fs = object.fontStyle; + // see comments in _getRealMatrix() + if(matrix && fs){ + object.matrix = dojox.gfx.matrix.multiply(matrix, {dy: dojox.gfx.normalizedLength(fs.size) * 0.35}); + } + }; + + var attachPath = function(object){ + // summary: builds a path shape from a Node. + // object: dojox.gfx.Shape: an VML shape + var shape = object.shape = dojo.clone(dojox.gfx.defaultPath), + p = rawNode.path.v.match(dojox.gfx.pathVmlRegExp), + t = [], skip = false, map = dojox.gfx.Path._pathVmlToSvgMap; + for(var i = 0; i < p.length; ++p){ + var s = p[i]; + if(s in map) { + skip = false; + t.push(map[s]); + } else if(!skip){ + var n = parseInt(s); + if(isNaN(n)){ + skip = true; + }else{ + t.push(n); + } + } + } + var l = t.length; + if(l >= 4 && t[l - 1] == "" && t[l - 2] == 0 && t[l - 3] == 0 && t[l - 4] == "l"){ + t.splice(l - 4, 4); + } + if(l){ + shape.path = t.join(" "); + } + }; +})(); -- cgit v1.2.3-54-g00ecf