Update of /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18901/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure Modified Files: SvgDocument.cs SvgElementInstance.cs SvgSymbolElement.cs SvgTransformableElement.cs SvgUseElement.cs Log Message: Library wide fixes for Unit Test completion, only Mutation events left to implement for current test coverage Index: SvgSymbolElement.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgSymbolElement.cs,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- SvgSymbolElement.cs 27 May 2003 20:44:00 -0000 1.5 +++ SvgSymbolElement.cs 23 Oct 2005 23:39:29 -0000 1.6 @@ -40,6 +40,8 @@ return svgFitToViewBox.PreserveAspectRatio; } } - #endregion + #endregion + + } } Index: SvgElementInstance.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgElementInstance.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- SvgElementInstance.cs 6 Mar 2005 08:07:04 -0000 1.1 +++ SvgElementInstance.cs 23 Oct 2005 23:39:29 -0000 1.2 @@ -10,19 +10,8 @@ public SvgElementInstance(XmlNode refNode, SvgUseElement useElement, SvgElementInstance parent) { correspondingUseElement = (ISvgUseElement)useElement; - parentNode = (SvgElementInstance)parent; - - if(refNode is SvgElement) - { - correspondingElement = (ISvgElement)refNode; - ((SvgElement)refNode).ElementInstance = this; - } - else - { - correspondingElement = null; - } - + correspondingElement = (ISvgElement)refNode; eventTarget = new EventTarget(this); } Index: SvgTransformableElement.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgTransformableElement.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- SvgTransformableElement.cs 6 Mar 2005 08:07:04 -0000 1.1 +++ SvgTransformableElement.cs 23 Oct 2005 23:39:29 -0000 1.2 @@ -59,10 +59,10 @@ public ISvgRect GetBBox() { - return new SvgRect(GetBRect()); + return new SvgRect(GetBRect(0)); } - public RectangleF GetBRect() + public RectangleF GetBRect(float margin) { if(this is ISharpGDIPath) { @@ -70,18 +70,23 @@ GraphicsPath gp = gdiPathElm.GetGraphicsPath(); SvgMatrix svgMatrix = (SvgMatrix)this.GetScreenCTM(); RectangleF bounds = gp.GetBounds(svgMatrix.ToMatrix()); - bounds = RectangleF.Inflate(bounds, 20, 20); + bounds = RectangleF.Inflate(bounds, margin, margin); return bounds; } else if (this is ISvgUseElement) { SvgUseElement use = (SvgUseElement)this; + SvgTransformableElement refEl = use.ReferencedElement as SvgTransformableElement; + if (refEl == null) + return RectangleF.Empty; + XmlElement refElParent = (XmlElement)refEl.ParentNode; OwnerDocument.Static = true; - XmlNode parent = ParentNode; - SvgGElement newChild = use.WrappedReferencedElement; - parent.ReplaceChild(newChild, this); - RectangleF bbox = newChild.GetBRect(); - parent.ReplaceChild(this, newChild); + use.CopyToReferencedElement(refEl); + this.AppendChild(refEl); + RectangleF bbox = refEl.GetBRect(margin); + this.RemoveChild(refEl); + use.RestoreReferencedElement(refEl); + refElParent.AppendChild(refEl); OwnerDocument.Static = false; return bbox; } @@ -96,7 +101,7 @@ if (childNode is ISvgTransformable) { transformChild = (SvgTransformableElement)childNode; - RectangleF bbox = transformChild.GetBRect(); + RectangleF bbox = transformChild.GetBRect(margin); if (bbox != RectangleF.Empty) { if(union == RectangleF.Empty) union = bbox; @@ -236,7 +241,10 @@ if (renderingNode.ScreenRegion != RectangleF.Empty) return; - renderingNode.ScreenRegion = GetBRect(); + //TODO this is still fairly experimental, a margin of 20 gives us some overlap for leeway + //TODO in general, overlap is necessary to handle strokes, which are not covered in bbox, but are + //TODO for rendering purposes (same with markers) + renderingNode.ScreenRegion = GetBRect(0); } } Index: SvgDocument.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgDocument.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- SvgDocument.cs 6 Mar 2005 08:07:04 -0000 1.1 +++ SvgDocument.cs 23 Oct 2005 23:39:29 -0000 1.2 @@ -607,7 +607,7 @@ if (res == null) return null; else - return (XmlElement)res; + return (Element)res; } #endregion Index: SvgUseElement.cs =================================================================== RCS file: /cvsroot/svgdomcsharp/SharpVectorGraphics/src/SharpVectorObjectModel/SharpVectors/dom/svg/Document Structure/SvgUseElement.cs,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- SvgUseElement.cs 6 Mar 2005 08:07:04 -0000 1.1 +++ SvgUseElement.cs 23 Oct 2005 23:39:29 -0000 1.2 @@ -3,6 +3,7 @@ using System.Drawing; using SharpVectors.Dom.Svg.Rendering; using SharpVectors.Dom.Css; +using System.Collections; namespace SharpVectors.Dom.Svg { @@ -18,72 +19,6 @@ } #endregion - #region Private members - private SvgGElement gElm = null; - public SvgGElement WrappedReferencedElement - { - get - { - if (gElm == null) - { - gElm = (SvgGElement)OwnerDocument.CreateElement(String.Empty, "g", SvgDocument.SvgNamespace); - foreach ( XmlNode att in Attributes ) - { - if ( att.LocalName != "x" && - att.LocalName != "y" && - att.LocalName != "width" && - att.LocalName != "height" && - !(att.LocalName == "href" && att.NamespaceURI == SvgDocument.XLinkNamespace)) - { - gElm.SetAttribute(att.LocalName, att.Value); - } - } - - gElm.SetAttribute("transform", - GetAttribute("transform") + " translate(" + X.AnimVal.Value + "," + Y.AnimVal.Value + ")"); - - XmlElement refElm = ReferencedElement; - - if ( refElm is SvgSymbolElement ) - { - SvgSvgElement svgElm = (SvgSvgElement)OwnerDocument.CreateElement(String.Empty, "svg", SvgDocument.SvgNamespace); - svgElm.SetAttribute("width", (HasAttribute("width")) ? GetAttribute("width") : "100%"); - svgElm.SetAttribute("height", (HasAttribute("height")) ? GetAttribute("height") : "100%"); - - foreach (XmlNode att in refElm.Attributes ) - { - if ( att.NamespaceURI.Length == 0 && att.LocalName != "width" && att.LocalName != "height") - { - svgElm.SetAttribute(att.LocalName, att.Value); - } - } - - foreach(XmlNode child in refElm.ChildNodes) - { - svgElm.AppendChild(OwnerDocument.ImportNode(child.Clone(), true)); - //svgElm.AppendChild(child.Clone()); - } - gElm.AppendChild(svgElm); - } - else if ( refElm is SvgSvgElement ) - { - SvgSvgElement svgElm = (SvgSvgElement)OwnerDocument.ImportNode(refElm.Clone(), true); - if (HasAttribute("width")) - svgElm.SetAttribute("width", GetAttribute("width")); - if (HasAttribute("height")) - svgElm.SetAttribute("height", GetAttribute("height")); - gElm.AppendChild(svgElm); - } - else if ( refElm != null ) - { - gElm.AppendChild(OwnerDocument.ImportNode(refElm.Clone(), true)); - } - } - return gElm; - } - } - #endregion - #region Implementation of ISvgUseElement private ISvgAnimatedLength x; public ISvgAnimatedLength X @@ -144,7 +79,7 @@ { if(instanceRoot == null) { - instanceRoot = new SvgElementInstance(WrappedReferencedElement.FirstChild, this, null); + instanceRoot = new SvgElementInstance(ReferencedElement, this, null); } return instanceRoot; } @@ -222,19 +157,15 @@ { case "x": x = null; - gElm = null; return; case "y": y = null; - gElm = null; return; case "width": width = null; - gElm = null; return; case "height": height = null; - gElm = null; return; } } @@ -244,45 +175,82 @@ { case "href": instanceRoot = null; - gElm = null; break; } } - if (gElm != null) - { - // Try to pass the attribute onto the conceptual tree - gElm.SetAttribute(attribute.LocalName, attribute.NamespaceURI, attribute.Value); - return; - } - base.HandleAttributeChange(attribute); } public void ReferencedNodeChange(Object src, XmlNodeChangedEventArgs args) { - //!!!!!!!!!!!!!!!! This is getting called too often! + //TODO - This is getting called too often! //instanceRoot = null; - //gElm = null; } - #endregion + #endregion + + #region Rendering + private string saveTransform = null; + private string saveWidth = null; + private string saveHeight = null; + public void CopyToReferencedElement(XmlElement refEl) + { + // X and Y become a translate portion of any transform, width and height may get passed on + if (X.AnimVal.Value != 0 || Y.AnimVal.Value != 0) + { + saveTransform = this.GetAttribute("transform"); + this.SetAttribute("transform", saveTransform + " translate(" + X.AnimVal.Value + "," + Y.AnimVal.Value + ")"); + } + if (refEl is SvgSymbolElement) + { + refEl.SetAttribute("width", (HasAttribute("width")) ? GetAttribute("width") : "100%"); + refEl.SetAttribute("height", (HasAttribute("height")) ? GetAttribute("height") : "100%"); + } + if (refEl is SvgSymbolElement) + { + saveWidth = refEl.GetAttribute("width"); + saveHeight = refEl.GetAttribute("height"); + if (HasAttribute("width")) + refEl.SetAttribute("width", GetAttribute("width")); + if (HasAttribute("height")) + refEl.SetAttribute("height", GetAttribute("height")); + } + } + + public void RestoreReferencedElement(XmlElement refEl) + { + if (saveTransform != null) + this.SetAttribute("transform", saveTransform); + if (saveWidth != null) + { + refEl.SetAttribute("width", saveWidth); + refEl.SetAttribute("height", saveHeight); + } + } - #region Rendering public override void Render(ISvgRenderer renderer) { + XmlElement refEl = ReferencedElement; + if (refEl == null) + return; + XmlElement refElParent = (XmlElement)refEl.ParentNode; OwnerDocument.Static = true; - XmlNode parent = ParentNode; - SvgGElement newChild = WrappedReferencedElement; - // todo: there has to be a better time to do this (e.g. trigger the instance tree creation)? - ISvgElementInstance inst = InstanceRoot; - parent.ReplaceChild(newChild, this); - newChild.Render(renderer); - parent.ReplaceChild(this, newChild); + CopyToReferencedElement(refEl); + refElParent.RemoveChild(refEl); + this.AppendChild(refEl); + base.Render(renderer); + this.RemoveChild(refEl); + RestoreReferencedElement(refEl); + refElParent.AppendChild(refEl); OwnerDocument.Static = false; } public override void CacheRenderingRegion(ISvgRenderer renderer) { + SvgTransformableElement refEl = ReferencedElement as SvgTransformableElement; + if (refEl == null) + return; + if(renderingNode == null) { renderingNode = renderer.GetRenderingNode(this); @@ -292,13 +260,16 @@ if (renderingNode != null && renderingNode.ScreenRegion != RectangleF.Empty) return; + XmlElement refElParent = (XmlElement)refEl.ParentNode; OwnerDocument.Static = true; - XmlNode parent = ParentNode; - SvgGElement newChild = WrappedReferencedElement; - parent.ReplaceChild(newChild, this); - newChild.CacheRenderingRegion(renderer); - renderingNode.ScreenRegion = newChild.RenderingNode.ScreenRegion; - parent.ReplaceChild(this, newChild); + CopyToReferencedElement(refEl); + refElParent.RemoveChild(refEl); + this.AppendChild(refEl); + refEl.CacheRenderingRegion(renderer); + renderingNode.ScreenRegion = refEl.RenderingNode.ScreenRegion; + this.RemoveChild(refEl); + RestoreReferencedElement(refEl); + refElParent.AppendChild(refEl); OwnerDocument.Static = false; } @@ -306,9 +277,8 @@ { if (renderingNode != null) renderingNode.ScreenRegion = RectangleF.Empty; - // Invalidate the shadow tree - SvgGElement newChild = WrappedReferencedElement; - newChild.InvalidateRenderingRegion(); + if (ReferencedElement != null && ReferencedElement is SvgElement) + ((SvgElement)ReferencedElement).InvalidateRenderingRegion(); } #endregion |