From: Jeff R. <jef...@us...> - 2005-11-19 03:13:35
|
Update of /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SvgComponents In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12283/src/SvgComponents Modified Files: SvgComponents.csproj SvgPictureBox.cs Log Message: Library wide changes for scripting support and automated re-rendering Index: SvgPictureBox.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SvgComponents/SvgPictureBox.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- SvgPictureBox.cs 11 Sep 2005 18:31:10 -0000 1.2 +++ SvgPictureBox.cs 19 Nov 2005 03:13:24 -0000 1.3 @@ -9,14 +9,26 @@ using System.Windows.Forms; using System.Xml; using System.Reflection; +using System.Text; +using System.Security; +using System.Security.Permissions; + +using SharpVectors.Dom.Events; using SharpVectors.Dom.Svg; using SharpVectors.Xml; using SharpVectors.Renderer.Gdi; +using SharpVectors.Renderer; +using SharpVectors.Dom.Svg.Rendering; using SharpVectors.Dom; using SharpVectors.Dom.Css; +using SharpVectors.Scripting; +using SharpVectors.Collections; +using SharpVectors.Net; using System.Threading; +[assembly: AllowPartiallyTrustedCallers] + namespace SvgComponents { public class SvgPictureBox : System.Windows.Forms.Control @@ -35,12 +47,42 @@ SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.DoubleBuffer, true); + scriptEngineByMimeType = new TypeDictionary(); + SetMimeTypeEngineType("application/ecmascript", typeof(JScriptEngine)); + renderer = new GdiRenderer(); + renderer.OnRender = new RenderEvent(this.OnRender); window = new SvgWindow(this, renderer); } #endregion #region Events + public void OnRender(RectangleF updatedRect) + { + if (surface != null) + { + if (updatedRect == RectangleF.Empty) + Draw(surface); + else + Draw(surface, updatedRect); + } + else + { + surface = CreateGraphics(); + if (updatedRect == RectangleF.Empty) + Draw(surface); + else + Draw(surface, updatedRect); + surface.Dispose(); + surface = null; + } + + // Collect the rendering regions for later updates + SvgDocument doc = (window.Document as SvgDocument); + SvgElement root = (doc.RootElement as SvgElement); + //root.CacheRenderingRegion(renderer); + } + private int lastX = -1; private int lastY = -1; protected override void OnMouseMove(MouseEventArgs e) @@ -139,16 +181,22 @@ if(value != null && value.Length > 0) { + // Load the source window.Src = value; + // Initialize the style sheets SetupStyleSheets(); + // Execute all script elements + UnloadEngines(); + InitializeEvents(); + ExecuteScripts(); //JR if (autoSize) { ISvgSvgElement svgEl = window.Document.RootElement; this.Width = (int)svgEl.Width.BaseVal.Value; this.Height = (int)svgEl.Height.BaseVal.Value; - ((CssXmlElement)svgEl).CssInvalidate(); } + renderer.InvalidRect = RectangleF.Empty; Render(); loaded = true; } @@ -168,6 +216,11 @@ try { #endif + // Worry about clearing the graphics nodes map... + renderer.ClearMap(); + System.GC.Collect(); + System.Threading.Thread.Sleep(1); + if(xml != null && xml.Length > 0) { if(xml != null && xml.Length > 0) @@ -200,8 +253,6 @@ { if ( this.window != null ) { renderAndInvalidate(); - System.GC.Collect(); - System.Threading.Thread.Sleep(1); } } @@ -252,21 +303,6 @@ #endif renderer.Render(window.Document as SvgDocument); - if (surface != null) - Draw(surface); - else - { - surface = CreateGraphics(); - Draw(surface); - surface.Dispose(); - surface = null; - } - - // Collect the rendering regions for later updates - SvgDocument doc = (window.Document as SvgDocument); - SvgElement root = (doc.RootElement as SvgElement); - root.CacheRenderingRegion(renderer); - #if RELEASE } catch(Exception e) @@ -278,30 +314,25 @@ private void updateAndInvalidate(RectangleF rect) { -#if RELEASE - try - { -#endif renderer.InvalidateRect(rect); - renderer.Render(window.Document as SvgDocument); + renderAndInvalidate(); + } - if (surface != null) - Draw(surface, rect); - else + public void DrawTo(IntPtr hdc) + { + if ( !this.DesignMode ) { - surface = CreateGraphics(); - Draw(surface, rect); - surface.Dispose(); - surface = null; + if ( window != null ) + { + GraphicsWrapper gw = GraphicsWrapper.FromHdc(hdc, true); + GdiRenderer r = ((GdiRenderer)window.Renderer); + gw.Clear(r.BackColor); + r.GraphicsWrapper = gw; + window.Renderer.Render((SvgDocument)window.Document); + r.GraphicsWrapper = null; + gw.Dispose(); + } } - -#if RELEASE - } - catch(Exception e) - { - MessageBox.Show("An exception occured while rendering: " + e.Message); - } -#endif } public void Draw(Graphics gr) @@ -396,6 +427,212 @@ } #endregion + #region Scripting Methods and Properties + private TypeDictionary scriptEngineByMimeType; + private Hashtable scriptEngines = new Hashtable(); + + public void SetMimeTypeEngineType(string mimeType, Type engineType) + { + scriptEngineByMimeType[mimeType] = engineType; + } + + public ScriptEngine GetScriptEngineByMimeType(string mimeType) + { + ScriptEngine engine = null; + + if (mimeType == "") + mimeType = ((ISvgWindow)window).Document.RootElement.GetAttribute("contentScriptType"); + + if (mimeType == "" || mimeType == "text/ecmascript" || mimeType == "text/javascript" || mimeType == "application/javascript") + mimeType = "application/ecmascript"; + + if (!scriptEngines.Contains(mimeType)) + { + object[] args = new object[] { (window as ISvgWindow) }; + engine = (ScriptEngine)scriptEngineByMimeType.CreateInstance(mimeType, args); + scriptEngines.Add(mimeType,engine); + engine.Initialise(); + } + + if (engine == null) + engine = (ScriptEngine) scriptEngines[mimeType]; + + return engine; + } + + + /// <summary> + /// Clears the existing script engine list from any previously running instances + /// </summary> + private void UnloadEngines() + { + // Dispose of all running engines from previous document instances + foreach (string mimeType in scriptEngines.Keys) + { + ScriptEngine engine = (ScriptEngine)scriptEngines[mimeType]; + engine.Close(); + engine = null; + } + // Clear the list + scriptEngines.Clear(); + ClosureEventMonitor.Clear(); + ScriptTimerMonitor.Reset(); + } + + /// <summary> + /// Add event listeners for on* events within the document + /// </summary> + private void InitializeEvents() + { + SvgDocument document = (SvgDocument)window.Document; + document.NamespaceManager.AddNamespace("svg", "http://www.w3.org/2000/svg"); + + XmlNodeList nodes = document.SelectNodes(@"//*[namespace-uri()='http://www.w3.org/2000/svg'] + [local-name()='svg' or + local-name()='g' or + local-name()='defs' or + local-name()='symbol' or + local-name()='use' or + local-name()='switch' or + local-name()='image' or + local-name()='path' or + local-name()='rect' or + local-name()='circle' or + local-name()='ellipse' or + local-name()='line' or + local-name()='polyline' or + local-name()='polygon' or + local-name()='text' or + local-name()='tref' or + local-name()='tspan' or + local-name()='textPath' or + local-name()='altGlyph' or + local-name()='a' or + local-name()='foreignObject'] + /@*[name()='onfocusin' or + name()='onfocusout' or + name()='onactivate' or + name()='onclick' or + name()='onmousedown' or + name()='onmouseup' or + name()='onmouseover' or + name()='onmousemove' or + name()='onmouseout' or + name()='onload']", document.NamespaceManager); + + foreach (XmlNode node in nodes) + { + IAttribute att = (IAttribute)node; + IEventTarget targ = (IEventTarget)att.OwnerElement; + ScriptEventMonitor mon = new ScriptEventMonitor((VsaScriptEngine)GetScriptEngineByMimeType(""), att, window); + string eventName = null; + switch (att.Name) + { + case "onfocusin": + eventName = "focusin"; + break; + case "onfocusout": + eventName = "focusout"; + break; + case "onactivate": + eventName = "activate"; + break; + case "onclick": + eventName = "click"; + break; + case "onmousedown": + eventName = "mousedown"; + break; + case "onmouseup": + eventName = "mouseup"; + break; + case "onmouseover": + eventName = "mouseover"; + break; + case "onmousemove": + eventName = "mousemove"; + break; + case "onmouseout": + eventName = "mouseout"; + break; + case "onload": + eventName = "SVGLoad"; + break; + } + targ.AddEventListener(eventName, new EventListener(mon.EventHandler), false); + } + } + + /// <summary> /// Collect the text in all script elements, build engine and execute. /// </summary> + private void ExecuteScripts() + { + Hashtable codeByMimeType = new Hashtable(); + StringBuilder codeBuilder; + SvgDocument document = (SvgDocument)window.Document; + + XmlNodeList scripts = document.GetElementsByTagName("script", SvgDocument.SvgNamespace); + StringBuilder code = new StringBuilder(); + + foreach ( XmlElement script in scripts ) + { + string type = script.GetAttribute("type"); + + if ( GetScriptEngineByMimeType(type) != null ) + { + // make sure we have a StringBuilder for this MIME type + if ( !codeByMimeType.Contains(type) ) + codeByMimeType[type] = new StringBuilder(); + + // grab this MIME type's codeBuilder + codeBuilder = (StringBuilder) codeByMimeType[type]; + + if ( script.HasChildNodes ) + { + // process each child that is text node or a CDATA section + foreach ( XmlNode node in script.ChildNodes ) + { + if ( node.NodeType == XmlNodeType.CDATA || node.NodeType == XmlNodeType.Text ) + { + codeBuilder.Append(node.Value); + } + } + } + + if (script.HasAttribute("href", "http://www.w3.org/1999/xlink")) + { + string href = script.GetAttribute("href", "http://www.w3.org/1999/xlink"); + Uri baseUri = new Uri(((XmlDocument)((ISvgWindow)window).Document).BaseURI); + Uri hUri = new Uri(baseUri, href); + ExtendedHttpWebRequestCreator creator = new ExtendedHttpWebRequestCreator(); + ExtendedHttpWebRequest request = (ExtendedHttpWebRequest)creator.Create(hUri); + ExtendedHttpWebResponse response = (ExtendedHttpWebResponse)request.GetResponse(); + Stream rs = response.GetResponseStream(); + StreamReader sr = new StreamReader(rs); + codeBuilder.Append(sr.ReadToEnd()); + rs.Close(); + } + } + } + + // execute code for all script engines + foreach ( string mimeType in codeByMimeType.Keys ) + { + codeBuilder = (StringBuilder) codeByMimeType[mimeType]; + + if ( codeBuilder.Length > 0 ) + { + ScriptEngine engine = GetScriptEngineByMimeType(mimeType); + engine.Execute( codeBuilder.ToString() ); + } + } + + // load the root element + ((ISvgWindow)window).Document.RootElement.DispatchEvent(new Event("SVGLoad", false, true)); + } + + #endregion + + #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify @@ -411,6 +648,8 @@ /// </summary> protected override void Dispose( bool disposing ) { + renderer.Dispose(); + if( disposing ) { if(components != null) Index: SvgComponents.csproj =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SvgComponents/SvgComponents.csproj,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- SvgComponents.csproj 12 Sep 2005 15:08:23 -0000 1.14 +++ SvgComponents.csproj 19 Nov 2005 03:13:24 -0000 1.15 @@ -179,6 +179,21 @@ Project = "{FE34CBC0-D23C-4A95-BA64-83A031814010}" Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" /> + <Reference + Name = "Microsoft.Vsa" + AssemblyName = "Microsoft.Vsa" + HintPath = "..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Microsoft.Vsa.dll" + /> + <Reference + Name = "Microsoft.JScript" + AssemblyName = "Microsoft.JScript" + HintPath = "..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Microsoft.JScript.dll" + /> + <Reference + Name = "SharpVectorScripting" + Project = "{2C56C191-EB9D-4658-84EE-73D2605896E6}" + Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" + /> </References> </Build> <Files> |