From: Jeff R. <jef...@us...> - 2005-11-19 03:13:37
|
Update of /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12283/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure Modified Files: SvgDocument.cs SvgSvgElement.cs SvgTransformableElement.cs SvgWindow.cs Log Message: Library wide changes for scripting support and automated re-rendering Index: SvgDocument.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgDocument.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- SvgDocument.cs 23 Oct 2005 23:39:29 -0000 1.2 +++ SvgDocument.cs 19 Nov 2005 03:13:23 -0000 1.3 @@ -587,12 +587,12 @@ { collectedIds = new Hashtable(); // TODO: handle xml:id, handle duplicate ids? - XmlNodeList ids = this.SelectNodes("//*/@id"); + XmlNodeList ids = this.SelectNodes("//*/@id"); foreach (XmlAttribute node in ids) { try { - collectedIds.Add(node.Value, node.OwnerElement); + collectedIds.Add(node.Value, node.OwnerElement); } catch (Exception) { Index: SvgSvgElement.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgSvgElement.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- SvgSvgElement.cs 11 Sep 2005 18:26:49 -0000 1.2 +++ SvgSvgElement.cs 19 Nov 2005 03:13:23 -0000 1.3 @@ -1,5 +1,8 @@ using System; using System.Xml; +using System.Collections; +using System.Drawing; +using System.Timers; namespace SharpVectors.Dom.Svg { @@ -26,6 +29,11 @@ { return CurrentView.ZoomAndPan; } + set + { + throw new NotImplementedException(); + } + } #endregion @@ -138,6 +146,10 @@ { return GetAttribute("contentScriptType"); } + set + { + SetAttribute("contentScriptType", value); + } } /// <summary> @@ -150,6 +162,10 @@ { return GetAttribute("contentStyleType"); } + set + { + SetAttribute("contentStyleType", value); + } } @@ -335,6 +351,7 @@ if (this == OwnerDocument.RootElement) { // TODO: Invalidate! Fire OnZoom + currentView = null; currentScale = value; cachedViewBoxTransform = null; viewport = null; @@ -487,19 +504,47 @@ currentTranslate = CreateSvgPoint(); } return currentTranslate; - } else + } + else return OwnerDocument.RootElement.CurrentTranslate; } } + private ArrayList redrawTimers = new ArrayList(); + + public void RedrawTimerElapsed(object source, ElapsedEventArgs args) + { + UnsuspendRedraw(((Timer)source).GetHashCode()); + } + /// <summary> - /// Takes a time-out value which indicates that redraw shall not occur until: (a) the corresponding unsuspendRedraw(suspend_handle_id) call has been made, (b) an unsuspendRedrawAll() call has been made, or (c) its timer has timed out. In environments that do not support interactivity (e.g., print media), then redraw shall not be suspended. suspend_handle_id = suspendRedraw(max_wait_milliseconds) and unsuspendRedraw(suspend_handle_id) must be packaged as balanced pairs. When you want to suspend redraw actions as a collection of SVG DOM changes occur, then precede the changes to the SVG DOM with a method call similar to suspend_handle_id = suspendRedraw(max_wait_milliseconds) and follow the changes with a method call similar to unsuspendRedraw(suspend_handle_id). Note that multiple suspendRedraw calls can be used at once and that each such method call is treated independently of the other suspendRedraw method calls. + /// Takes a time-out value which indicates that redraw shall not occur until: (a) the + /// corresponding unsuspendRedraw(suspend_handle_id) call has been made, (b) an + /// unsuspendRedrawAll() call has been made, or (c) its timer has timed out. In + /// environments that do not support interactivity (e.g., print media), then redraw shall + /// not be suspended. suspend_handle_id = suspendRedraw(max_wait_milliseconds) and + /// unsuspendRedraw(suspend_handle_id) must be packaged as balanced pairs. When you + /// want to suspend redraw actions as a collection of SVG DOM changes occur, then + /// precede the changes to the SVG DOM with a method call similar to + /// suspend_handle_id = suspendRedraw(max_wait_milliseconds) and follow the changes with + /// a method call similar to unsuspendRedraw(suspend_handle_id). Note that multiple + /// suspendRedraw calls can be used at once and that each such method call is treated + /// independently of the other suspendRedraw method calls. /// </summary> - /// <param name="max_wait_milliseconds">The amount of time in milliseconds to hold off before redrawing the device. Values greater than 60 seconds will be truncated down to 60 seconds.</param> + /// <param name="max_wait_milliseconds">The amount of time in milliseconds to hold off + /// before redrawing the device. Values greater than 60 seconds will be truncated + /// down to 60 seconds.</param> /// <returns>A number which acts as a unique identifier for the given suspendRedraw() call. This value must be passed as the parameter to the corresponding unsuspendRedraw() method call.</returns> public int SuspendRedraw(int maxWaitMilliseconds) { - throw new NotImplementedException(); + if (maxWaitMilliseconds > 60000) + maxWaitMilliseconds = 60000; + Timer t = new Timer(maxWaitMilliseconds); + t.AutoReset = false; + t.Elapsed += new ElapsedEventHandler(this.RedrawTimerElapsed); + t.Enabled = true; + redrawTimers.Add(t); + return t.GetHashCode(); } /// <summary> @@ -509,17 +554,40 @@ /// <exception cref="DomException">This method will raise a DOMException with value NOT_FOUND_ERR if an invalid value (i.e., no such suspend_handle_id is active) for suspend_handle_id is provided.</exception> public void UnsuspendRedraw(int suspendHandleId) { - throw new NotImplementedException(); + Timer timer = null; + foreach (Timer t in redrawTimers) + { + if (t.GetHashCode() == suspendHandleId) + { + timer = t; + break; + } + } + if (timer == null) + throw new DomException(DomExceptionType.NotFoundErr, "Invalid handle submitted to unsuspendRedraw"); + + timer.Enabled = false; + redrawTimers.Remove(timer); + if (OwnerDocument.Window.Renderer.InvalidRect != RectangleF.Empty) + OwnerDocument.Window.Renderer.Render((ISvgDocument)OwnerDocument); + } /// <summary> - /// Cancels all currently active suspendRedraw() method calls. This method is most useful + /// Cancels all currently active suspendRedraw() method calls. This method is most + /// useful /// at the very end of a set of SVG DOM calls to ensure that all pending suspendRedraw() /// method calls have been cancelled. /// </summary> public void UnsuspendRedrawAll() { - throw new NotImplementedException(); + foreach (Timer t in redrawTimers) + { + t.Enabled = false; + } + redrawTimers.Clear(); + if (OwnerDocument.Window.Renderer.InvalidRect != RectangleF.Empty) + OwnerDocument.Window.Renderer.Render((ISvgDocument)OwnerDocument); } /// <summary> @@ -528,7 +596,8 @@ /// </summary> public void ForceRedraw() { - throw new NotImplementedException(); + OwnerDocument.Window.Renderer.InvalidRect = RectangleF.Empty; + OwnerDocument.Window.Renderer.Render((ISvgDocument)OwnerDocument); } /// <summary> @@ -807,21 +876,45 @@ public void Resize() { + // TODO: Invalidate! Fire SVGResize + width = null; + height = null; + x = null; + y = null; + currentView = null; + cachedViewBoxTransform = null; + viewport = null; + svgFitToViewBox = null; + svgFitToViewBox = new SvgFitToViewBox(this); if (this == OwnerDocument.RootElement) { - // TODO: Invalidate! Fire SVGResize - cachedViewBoxTransform = null; - viewport = null; - width = null; - height = null; - x = null; - y = null; - svgFitToViewBox = null; - svgFitToViewBox = new SvgFitToViewBox(this); + // TODO } else (OwnerDocument.RootElement as SvgSvgElement).Resize(); } + + #region Update handling + public override void HandleAttributeChange(XmlAttribute attribute) + { + if(attribute.NamespaceURI.Length == 0) + { + switch(attribute.LocalName) + { + case "x": + case "y": + case "width": + case "height": + case "viewBox": + case "preserveAspectRatio": + Resize(); + break; + } + + base.HandleAttributeChange(attribute); + } + } + #endregion } } Index: SvgWindow.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgWindow.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- SvgWindow.cs 6 Mar 2005 08:07:04 -0000 1.1 +++ SvgWindow.cs 19 Nov 2005 03:13:23 -0000 1.2 @@ -8,282 +8,178 @@ using SharpVectors.Collections; using SharpVectors.Dom.Svg.Rendering; -using SharpVectors.Scripting; +using SharpVectors.Dom.Events; using SharpVectors.Xml; namespace SharpVectors.Dom.Svg { - public class SvgWindow : ISvgWindow - { - #region Contructors - [Obsolete("This constructor is obsolete and will be removed in future versions.")] - public SvgWindow(long innerWidth, long innerHeight) - { - this.innerWidth = innerWidth; - this.innerHeight = innerHeight; - } - - public SvgWindow(long innerWidth, long innerHeight, ISvgRenderer renderer) - { - this.renderer = renderer; - if(this.renderer != null) - { - this.renderer.Window = this; - } - - this.innerWidth = innerWidth; - this.innerHeight = innerHeight; - } + public class SvgWindow : ISvgWindow + { + #region Contructors + [Obsolete("This constructor is obsolete and will be removed in future versions.")] + public SvgWindow(long innerWidth, long innerHeight) + { + this.innerWidth = innerWidth; + this.innerHeight = innerHeight; + } - public SvgWindow(SvgWindow parentWindow, long innerWidth, long innerHeight) : this(innerWidth, innerHeight, parentWindow.Renderer) - { - this.parentWindow = parentWindow; - } + public SvgWindow(long innerWidth, long innerHeight, ISvgRenderer renderer) + { + this.renderer = renderer; + if(this.renderer != null) + { + this.renderer.Window = this; + } - public SvgWindow(Control control, ISvgRenderer renderer) - { - if ( control == null ) - { - throw new NullReferenceException( "control cannot be null" ); - } - else - { - this.control = control; - this.renderer = renderer; - this.renderer.Window = this; + this.innerWidth = innerWidth; + this.innerHeight = innerHeight; + } - // setup default script engines - // NOTE: I believe this is the only constructor where this is - // needed since this is the only constructor involving a - // potentially interactive SVG - scriptEngineByMimeType = new TypeDictionary(); + public SvgWindow(SvgWindow parentWindow, long innerWidth, long innerHeight) : this(innerWidth, innerHeight, parentWindow.Renderer) + { + this.parentWindow = parentWindow; + } - SetMimeTypeEngineType("text/jscript.net", typeof(JScriptEngine)); - } - } - #endregion + public SvgWindow(Control control, ISvgRenderer renderer) + { + if ( control == null ) + { + throw new NullReferenceException( "control cannot be null" ); + } + else + { + this.control = control; + this.renderer = renderer; + this.renderer.Window = this; + } + } + #endregion - #region Private fields - private Control control = null; - private Hashtable referencedWindows = new Hashtable(); - private Hashtable referencedFiles = new Hashtable(); - private TypeDictionary scriptEngineByMimeType; - #endregion + #region Private fields + private Control control = null; + private Hashtable referencedWindows = new Hashtable(); + private Hashtable referencedFiles = new Hashtable(); + #endregion - #region Public properties - private SvgWindow parentWindow = null; - public SvgWindow ParentWindow - { - get - { - return parentWindow; - } - } + #region Public properties + private SvgWindow parentWindow = null; + public SvgWindow ParentWindow + { + get + { + return parentWindow; + } + } - private ISvgRenderer renderer; - public ISvgRenderer Renderer - { - get { return renderer; } - set { renderer = value; } - } - #endregion + private ISvgRenderer renderer; + public ISvgRenderer Renderer + { + get { return renderer; } + set { renderer = value; } + } + #endregion - #region Public methods - public void SetMimeTypeEngineType(string mimeType, Type engineType) + #region Public methods + /// <summary> /// Create and assign an empty SvgDocument to this window. This is needed only in situations where the library user needs to create an SVG DOM tree outside of the usual LoadSvgDocument mechanism. /// </summary> + public SvgDocument CreateEmptySvgDocument() + { + return document = new SvgDocument(this); + } + #endregion + + #region Implementation of ISvgWindow + private long innerWidth; + public long InnerWidth + { + get + { + if(control != null) { - scriptEngineByMimeType[mimeType] = engineType; + return control.Width; } - - /// <summary> /// Create and assign an empty SvgDocument to this window. This is needed only in situations where the library user needs to create an SVG DOM tree outside of the usual LoadSvgDocument mechanism. /// </summary> - public SvgDocument CreateEmptySvgDocument() + else { - return document = new SvgDocument(this); + return innerWidth; } + } + set + { + this.innerWidth = value; + } + } - /*public void Render() + private long innerHeight; + public long InnerHeight + { + get + { + if(control != null) { - if ( this.document != null && renderer != null && InnerWidth > 0 && InnerHeight > 0 ) { - renderer.BeforeRender(); - document.Render(renderer); - renderer.AfterRender(); - } - }*/ - - public void Alert(string message) - { - MessageBox.Show(message); + return control.Height; } - #endregion - - #region Private Methods - /// <summary> /// Collect the text in all script elements, build engine and execute. Note that this is very rough right now...just trying to get a simple case working - KL /// </summary> - private void executeScripts() + else { - Hashtable codeByMimeType = new Hashtable(); - StringBuilder codeBuilder; - - XmlNodeList scripts = document.GetElementsByTagName("script", SvgDocument.SvgNamespace); - StringBuilder code = new StringBuilder(); - - foreach ( XmlElement script in scripts ) - { - string type = script.GetAttribute("type"); - - if ( scriptEngineByMimeType.Contains(type) ) - { - // 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 ) - { - code.Append(node.Value); - } - } - } - else - { - // need to handle potential external reference here - } - } - } - - // execute code for all script engines - foreach ( string mimeType in codeByMimeType.Keys ) - { - codeBuilder = (StringBuilder) codeByMimeType[mimeType]; - - if ( codeBuilder.Length > 0 ) - { - object[] args = new object[] { this }; - - ScriptEngine engine = (ScriptEngine) scriptEngineByMimeType.CreateInstance(mimeType, args); - engine.Execute( codeBuilder.ToString() ); - } - } + return innerHeight; } + } + set + { + this.innerHeight = value; + } + } - #endregion - - #region Implementation of ISvgWindow - private long innerWidth; - public long InnerWidth - { - get - { - if(control != null) - { - return control.Width; - } - else - { - return innerWidth; - } - } - set - { - this.innerWidth = value; - } - } - - private long innerHeight; - public long InnerHeight - { - get - { - if(control != null) - { - return control.Height; - } - else - { - return innerHeight; - } - } - set - { - this.innerHeight = value; - } - } - - public void ClearInterval(object interval) - { - - } - - public void ClearTimeout(object timeout) - { - - } - - public XmlDocumentFragment ParseXML(string source, XmlDocument document) - { - XmlDocumentFragment frag = document.CreateDocumentFragment(); - frag.InnerXml = source; - return frag; - } - - public string PrintNode(System.Xml.XmlNode node) - { - return node.OuterXml; - } + public XmlDocumentFragment ParseXML(string source, XmlDocument document) + { + XmlDocumentFragment frag = document.CreateDocumentFragment(); + frag.InnerXml = source; + return frag; + } - public object SetInterval(string code, long delay) - { - return null; - } + public string PrintNode(System.Xml.XmlNode node) + { + return node.OuterXml; + } - public object SetTimeout(string code, long delay) - { - return null; - } + public SharpVectors.Dom.Stylesheets.IStyleSheet DefaultStyleSheet + { + get + { + return null; + } + } - public SharpVectors.Dom.Stylesheets.IStyleSheet DefaultStyleSheet - { - get - { - return null; - } - } + private SvgDocument document; + public ISvgDocument Document + { + get + { + return document; + } + set + { + document = (SvgDocument)value; + } + } - private SvgDocument document; - public ISvgDocument Document - { - get - { - return document; - } - set - { - document = (SvgDocument)value; - } - } + public void Alert(string message) + { + MessageBox.Show(message); + } - public string Src - { - get - { - return (document != null) ? document.Url : String.Empty; - } - set - { - Uri uri = new Uri(new Uri(Application.ExecutablePath), value); + public string Src + { + get + { + return (document != null) ? document.Url : String.Empty; + } + set + { + Uri uri = new Uri(new Uri(Application.ExecutablePath), value); - document = new SvgDocument(this); - document.Load(uri.AbsoluteUri); - - // Execute all script elements - //executeScripts(); - } - } + document = new SvgDocument(this); + document.Load(uri.AbsoluteUri); + } + } /// <summary> /// This is expected to be called by the host @@ -297,6 +193,6 @@ if (Document != null && Document.RootElement != null) (Document.RootElement as SvgSvgElement).Resize(); } - #endregion - } + #endregion + } } Index: SvgTransformableElement.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgTransformableElement.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- SvgTransformableElement.cs 23 Oct 2005 23:39:29 -0000 1.2 +++ SvgTransformableElement.cs 19 Nov 2005 03:13:23 -0000 1.3 @@ -70,6 +70,11 @@ GraphicsPath gp = gdiPathElm.GetGraphicsPath(); SvgMatrix svgMatrix = (SvgMatrix)this.GetScreenCTM(); RectangleF bounds = gp.GetBounds(svgMatrix.ToMatrix()); + string strokeWidth = this.GetPropertyValue("stroke-width"); + if(strokeWidth.Length == 0) strokeWidth = "1px"; + SvgLength strokeWidthLength = new SvgLength(this, "stroke-width", SvgLengthDirection.Viewport, strokeWidth); + float sw = (float)strokeWidthLength.Value; + margin += sw; bounds = RectangleF.Inflate(bounds, margin, margin); return bounds; } @@ -250,6 +255,22 @@ #region Update handling + public override void CssInvalidate() + { + base.CssInvalidate(); + + if (renderingNode != null) + { + // Quick-cache + renderingNode.ScreenRegion = GetBRect(0); + OwnerDocument.Window.Renderer.InvalidateRect(renderingNode.ScreenRegion); + } + else + { + OwnerDocument.Window.Renderer.InvalidateRect(GetBRect(0)); + } + } + public override void HandleAttributeChange(XmlAttribute attribute) { if(attribute.NamespaceURI.Length == 0) |