Figure SvgElementToFigure(SvgElement e) { Figure f = null; if (e is SvgRectElement || e is SvgImageElement) { if (e.Attributes.ContainsKey("x") && e.Attributes.ContainsKey("y") && e.Attributes.ContainsKey("width") && e.Attributes.ContainsKey("height")) { SvgLength X = new SvgLength((string)e.Attributes["x"]); SvgLength Y = new SvgLength((string)e.Attributes["y"]); SvgLength Width = new SvgLength((string)e.Attributes["width"]); SvgLength Height = new SvgLength((string)e.Attributes["height"]); DRect r = new DRect(X.Value, Y.Value, Width.Value, Height.Value); if (e is SvgRectElement) f = new RectFigure(r, 0); else if (e is SvgImageElement) { SvgImageElement e2 = (SvgImageElement)e; byte[] imgData = Read(e2.Href); if (imgData != null) f = new BitmapFigure(r, 0, imgData, Path.GetFileName(e2.Href)); } } } else if (e is SvgEllipseElement) { SvgEllipseElement e2 = (SvgEllipseElement)e; if (e2.Attributes.ContainsKey("cx") && e2.Attributes.ContainsKey("cy") && e2.Attributes.ContainsKey("rx") && e2.Attributes.ContainsKey("ry")) { e2.CX = new SvgLength((string)e2.Attributes["cx"]); e2.CY = new SvgLength((string)e2.Attributes["cy"]); e2.RX = new SvgLength((string)e2.Attributes["rx"]); e2.RY = new SvgLength((string)e2.Attributes["ry"]); f = new EllipseFigure(new DRect(e2.CX.Value - e2.RX.Value, e2.CY.Value - e2.RY.Value, e2.RX.Value * 2, e2.RY.Value * 2), 0); } } else if (e is SvgPathElement) { SvgPathElement e2 = (SvgPathElement)e; if (e2.Attributes.ContainsKey("d")) { e2.D = new SvgPath((string)e2.Attributes["d"]); // treat all paths as polygons for the moment DPoints pts = new DPoints(); for (int i = 0; i < e2.D.Count; i++) { PathSeg s = e2.D[i]; if ((s.Type == SvgPathSegType.SVG_SEGTYPE_MOVETO || s.Type == SvgPathSegType.SVG_SEGTYPE_LINETO) && s.Abs) pts.Add(new DPoint(s.Data[0], s.Data[1])); } if (pts.Count >= 3) { DRect r = pts.Bounds(); foreach (DPoint pt in pts) { pt.X = (pt.X - r.Left) / r.Width; pt.Y = (pt.Y - r.Top) / r.Height; } f = new PolygonFigure(pts); f.Rect = r; } } } else if (e is SvgPolylineElement) { SvgPolylineElement e2 = (SvgPolylineElement)e; if (e2.Attributes.ContainsKey("points")) f = new PolylineFigure(DPoints.FromString((string)e2.Attributes["points"])); } else if (e is SvgLineElement) { SvgLineElement e2 = (SvgLineElement)e; if (e2.Attributes.ContainsKey("x1") && e2.Attributes.ContainsKey("y1") && e2.Attributes.ContainsKey("x2") && e2.Attributes.ContainsKey("y2")) { e2.X1 = new SvgLength((string)e2.Attributes["x1"]); e2.Y1 = new SvgLength((string)e2.Attributes["y1"]); e2.X2 = new SvgLength((string)e2.Attributes["x2"]); e2.Y2 = new SvgLength((string)e2.Attributes["y2"]); f = new LineFigure2(new DPoint(e2.X1.Value, e2.Y1.Value), new DPoint(e2.X2.Value, e2.Y2.Value)); } } else if (e is SvgGroupElement) { SvgGroupElement e2 = (SvgGroupElement)e; f = new GroupFigure(); GroupFigure gf = (GroupFigure)f; foreach (SvgElement childEle in e2.Children) { Figure childFig = SvgElementToFigure(childEle); if (childFig != null) gf.ChildFigures.Add(childFig); } if (gf.ChildFigures.Count > 0) gf.ChildFigures = gf.ChildFigures; else f = null; } else if (e is SvgTextElement) { double fontSize; string fontFamily; DColor fill; bool bold, italic, underline; string text = ExtractText(e, 0, out fontSize, out fontFamily, out fill, out bold, out italic, out underline); while (text.EndsWith("\n")) text = text.Substring(0, text.Length - 1); if (text != null) { DPoint translation = GetSvgElementTranslation((SvgTextElement)e); f = new TextFigure(translation, text, 0); ((TextFigure)f).FontSize = fontSize; ((TextFigure)f).FontName = fontFamily; ((TextFigure)f).Fill = fill; ((TextFigure)f).Bold = bold; ((TextFigure)f).Italics = italic; ((TextFigure)f).Underline = underline; // set wrap threshold const double editWidthMod = 1.435; if (((SvgTextElement)e).Attributes.ContainsKey(NBTextEditWidth)) { string editwidth = (string)((SvgTextElement)e).Attributes[NBTextEditWidth]; if (editwidth != null && editwidth.Length != 0) { ((TextFigure)f).WrapThreshold = double.Parse(editwidth) * editWidthMod; ((TextFigure)f).WrapFontSize = ((TextFigure)f).FontSize; ((TextFigure)f).WrapText = true; } } // scale DPoint scale = GetSvgElementScale((SvgTextElement)e); const double scaleMod = 0.694; f.Width *= scale.X * scaleMod; f.Height *= scale.Y * scaleMod; } } if (f != null) { if (e is SvgStyledTransformedElement) f.Rotation = GetSvgElementRotation((SvgStyledTransformedElement)e); if (f is IFillable && e.Attributes.ContainsKey("fill")) ((IFillable)f).Fill = DColor.FromHtml((string)e.Attributes["fill"]); if (f is IStrokeable) { if (e.Attributes.ContainsKey("stroke")) ((IStrokeable)f).Stroke = DColor.FromHtml((string)e.Attributes["stroke"]); if (e.Attributes.ContainsKey("stroke-width")) ((IStrokeable)f).StrokeWidth = double.Parse((string)e.Attributes["stroke-width"]); if (e.Attributes.ContainsKey("stroke-dasharray")) ((IStrokeable)f).StrokeStyle = NotebookDashArrayToStrokeStyle((string)e.Attributes["stroke-dasharray"]); } if (f is IMarkable) { if (e.Attributes.ContainsKey("marker-start")) ((IMarkable)f).StartMarker = NotebookMarkerToDMarker((string)e.Attributes["marker-start"]); if (e.Attributes.ContainsKey("marker-end")) ((IMarkable)f).EndMarker = NotebookMarkerToDMarker((string)e.Attributes["marker-end"]); } if (f is IAlphaBlendable && e.Attributes.ContainsKey("opacity")) ((IAlphaBlendable)f).Alpha = double.Parse((string)e.Attributes["opacity"]); applyLink(f, e); applyLock(f, e); } return f; }
void DoDrawingLineMouseUp(DTkViewer dv, DMouseButton btn, DPoint pt) { if (currentFigure is IPolyline) { if (!(currentFigure is IRepositionPoint)) { // test for finished line bool lineNotFinished = false; if (((IPolyline)currentFigure).Points.Count < 2) { if (UsePolylineDots) { DPoint currentPt = ((IPolyline)currentFigure).Points[0]; DPoint newPt = new DPoint(currentPt.X + 0.01, currentPt.Y + 0.01); ((IPolyline)currentFigure).Points.Add(newPt); } else lineNotFinished = true; } if (!lineNotFinished) { // simplify polyline if (SimplifyPolylines && currentFigure is IPolyline) { ((IPolyline)currentFigure).Points = DGeom.SimplifyPolyline(((IPolyline)currentFigure).Points, simplifyPolylinesTolerance); dv.Update(currentFigure.GetSelectRect()); } // auto group if (autoGroupPolylineTimeoutMet) { autoGroupPolylineXLimitMet = DGeom.DistXBetweenRects(autoGroupPolylineFigure.GetEncompassingRect(), currentFigure.GetEncompassingRect()) < autoGroupPolylinesXLimit; autoGroupPolylineYLimitMet = DGeom.DistYBetweenRects(autoGroupPolylineFigure.GetEncompassingRect(), currentFigure.GetEncompassingRect()) < autoGroupPolylinesYLimit; if (autoGroupPolylineXLimitMet && autoGroupPolylineYLimitMet) { if (autoGroupPolylineFigure is GroupFigure) { figureHandler.Remove(currentFigure); IChildFigureable cf = (IChildFigureable)autoGroupPolylineFigure; cf.ChildFigures.Add(currentFigure); cf.ChildFigures = cf.ChildFigures; } else if (autoGroupPolylineFigure is IPolyline) { figureHandler.Remove(autoGroupPolylineFigure); figureHandler.Remove(currentFigure); GroupFigure gf = new GroupFigure(new List<Figure>(new Figure[] { autoGroupPolylineFigure, currentFigure })); figureHandler.Add(gf, false); autoGroupPolylineFigure = gf; } } else autoGroupPolylineFigure = currentFigure; } } autoGroupPolylineStart = Environment.TickCount; } } // commit to undo/redo CommitOrRollback(false); // transition TransitionTo(DrawLineDefault); }
void ErasePolylines(DPoint eraserPt, IList<Figure> figures, ref DRect updateRect, GroupFigure parent) { for (int i = figures.Count - 1; i >= 0; i--) if (figures[i] is PolylinebaseFigure) { PolylinebaseFigure f = (PolylinebaseFigure)figures[i]; DPoint rotPt = f.TransformPointToFigure(eraserPt); DPoints ptsToRemove = new DPoints(); if (f.Points != null) foreach (DPoint pt in f.Points) if (DGeom.PointInCircle(pt, rotPt, figureHandler.EraserFigure.Size / 2)) ptsToRemove.Add(pt); if (ptsToRemove.Count > 0) { // add polyline figure bounding box to updateRect updateRect = updateRect.Union(GetBoundingBox(f)); if (parent != null) { // remove child figure and account for rect changes DRect oldR = parent.Rect; ErasePolyline(ptsToRemove, f, parent); DRect newR = parent.Rect; DGeom.UpdateRotationPosition(f, oldR, newR); } else ErasePolyline(ptsToRemove, f, parent); } } else if (figures[i] is GroupFigure) { GroupFigure f = (GroupFigure)figures[i]; // recurse into group figure and also update rotation position DRect oldR = f.Rect; ErasePolylines(f.TransformPointToFigure(eraserPt), f.ChildFigures, ref updateRect, f); DRect newR = f.Rect; DGeom.UpdateRotationPosition(f, oldR, newR); // clean up group figure if no longer needed if (f.ChildFigures.Count == 1) figureHandler.UngroupFigure(f); else if (f.ChildFigures.Count < 1) figures.Remove(f); } }
void ErasePolyline(DPoints ptsToRemove, PolylinebaseFigure f, GroupFigure parent) { // set figure list to use UndoRedoList<Figure> figs; if (parent != null) figs = parent.ChildFigures; else figs = figureHandler.Figures; // make new polylines List<Figure> newPolys = new List<Figure>(); DPoints newPts = null; Method createNewPoly = delegate() { if (newPts != null && newPts.Count >= 2) { PolylinebaseFigure nf = (PolylinebaseFigure)Activator.CreateInstance(f.GetType()); nf.Points = newPts; newPolys.Add(nf); } newPts = null; }; foreach (DPoint pt in f.Points) { if (!ptsToRemove.Contains(pt)) { if (newPts == null) newPts = new DPoints(); newPts.Add(new DPoint(pt.X, pt.Y)); } else createNewPoly(); } createNewPoly(); // apply old poly properties to new polys and add to "figs" figure list for (int i = 0; i < newPolys.Count; i++) { Figure nf = newPolys[i]; if (newPolys.Count == 1) ClonePolyProps(f, nf, LineSegPos.All); else if (i == 0) ClonePolyProps(f, nf, LineSegPos.Start); else if (i == newPolys.Count - 1) ClonePolyProps(f, nf, LineSegPos.End); else ClonePolyProps(f, nf, LineSegPos.Middle); // add poly to figs figs.Insert(figs.IndexOf(f), nf); } // remove original polyline figs.Remove(f); // reset GroupFigure parent figure list so its scalling boxes are reset if (parent != null) parent.ChildFigures = figs; }
public void UngroupFigure(GroupFigure gf) { // apply group properties (rotation etc) to child figures DPoint grpCtr = gf.Rect.Center; foreach (Figure f in gf.ChildFigures) { // flip DPoint ctr = f.Rect.Center; if (gf.FlipX) { f.FlipX = !f.FlipX; f.X -= (ctr.X - grpCtr.X) * 2; // flip rotation if (f.Rotation != 0) f.Rotation = 2 * Math.PI - f.Rotation; } if (gf.FlipY) { f.FlipY = !f.FlipY; f.Y -= (ctr.Y - grpCtr.Y) * 2; // flip rotation if (f.Rotation != 0) f.Rotation = 2 * Math.PI - f.Rotation; } // rotation if (gf.Rotation != 0) { ctr = f.Rect.Center; DPoint rotpt = DGeom.RotatePoint(ctr, grpCtr, gf.Rotation); f.X += rotpt.X - ctr.X; f.Y += rotpt.Y - ctr.Y; f.Rotation += gf.Rotation; } // alpha if (gf.UseRealAlpha && f is IAlphaBlendable) ((IAlphaBlendable)f).Alpha *= gf.Alpha; } // add group figures to figure list foreach (Figure f in gf.ChildFigures) Add(f, false); // remove group figures.Remove(gf); }
public void GroupFigures(List<Figure> figs) { if (CanGroupFigures(figs)) { // make group GroupFigure gf = new GroupFigure(figs); Add(gf, false); // change selected figures to the group ClearSelectedFiguresList(); AddToSelected(gf); DoSelectedFiguresChanged(); // remove child figures from figure list foreach (Figure f in figs) { figures.Remove(f); f.MouseOver = false; } } }