/// <summary> /// Loads the FlowChart document from a stream. /// </summary> public void LoadFromStream(Stream stream) { try { loading = true; SuspendLayout(); ClearAll(); PersistContext ctx = new PersistContext(stream, this); ctx.readHeader(); // read basic-type flowchart properties DocInfoVer1 docInfo1 = (DocInfoVer1)ctx.loadObject(); DocInfoVer2 docInfo2 = (DocInfoVer2)ctx.loadObject(); docInfo1.apply(this); docInfo2.apply(this); textFormat = ctx.loadStringFormat(); Font = ctx.loadFont(); BackgroundImage = ctx.loadImage(); // read diagram objects zOrder = (ChartObjectCollection)ctx.loadObject(); groups = (GroupCollection)ctx.loadObject(); selection = (Selection)ctx.loadObject(); ctx.loadReference(this); if (ctx.FileVersion > 2) { shapeTemplate = (ShapeTemplate)ctx.loadObject(); if (ctx.FileVersion > 3) { Brush.RestoreBrushes(this, new BinaryReader(stream), ctx); boxPen = (Pen)ctx.loadObject(); arrowPen = (Pen)ctx.loadObject(); tablePen = (Pen)ctx.loadObject(); ctx.loadReference(this); ctx.loadReference(this); ctx.loadReference(this); boxSelStyle = (HandlesStyle)ctx.reader.ReadInt32(); tableSelStyle = (HandlesStyle)ctx.reader.ReadInt32(); if (ctx.FileVersion > 4) { // new in save format 5 allowLinksRepeat = ctx.reader.ReadBoolean(); if (ctx.FileVersion > 5) { // new in save format 6 PolyTextLayout = ctx.reader.ReadBoolean(); ShapeOrientation = ctx.reader.ReadSingle(); if (ctx.FileVersion > 7) { // new in save format 8 routeArrows = ctx.reader.ReadBoolean(); arrowsRetainForm = ctx.reader.ReadBoolean(); arrowTextStyle = (ArrowTextStyle)ctx.reader.ReadInt32(); tableLinkStyle = (TableLinkStyle)ctx.reader.ReadInt32(); if (ctx.FileVersion >= 12) { // new in save format 12 measureUnit = (GraphicsUnit)ctx.reader.ReadInt32(); docExtentsMin = ctx.loadRectF(); if (ctx.FileVersion > 13) { // new in save format 14 expandBtnPos = (ExpandButtonPosition)ctx.reader.ReadInt32(); // not used anymore ctx.reader.ReadInt32(); ctx.reader.ReadInt32(); enableStyledText = ctx.reader.ReadBoolean(); usePolyTextLt = ctx.reader.ReadBoolean(); ctx.loadReference(this); // brush if (ctx.FileVersion > 16) { // new in save format 17 arrowText = ctx.reader.ReadString(); boxText = ctx.reader.ReadString(); arrowCrossings = (ArrowCrossings)ctx.reader.ReadInt32(); gridStyle = (GridStyle)ctx.reader.ReadInt32(); crossRadius = ctx.reader.ReadSingle(); if (ctx.FileVersion > 19) { // new in save format 20 ctx.loadReference(this); // exteriorBrush arrowsSnapToBorders = ctx.reader.ReadBoolean(); arrowSelStyle = (HandlesStyle)ctx.reader.ReadInt32(); if (ctx.FileVersion > 20) { // new in save format 21 Tag = null; bool tagAvailable = ctx.reader.ReadBoolean(); if (tagAvailable) Tag = ctx.loadTag(); if (ctx.FileVersion > 26) { // new in save format 27 roundedArrows = ctx.reader.ReadBoolean(); roundedArrowsRadius = ctx.reader.ReadSingle(); } } } } } } } } } } } // finish load ctx.loadRemainingObjects(); ctx.setReferences(); // add the objects to their specialized collections foreach (ChartObject obj in zOrder) addToObjColl(obj); foreach (Group group in groups) group.updateObjCol(); Brush.freeUnusedBrushes(); foreach (ChartObject obj in zOrder) obj.onLoad(); dirty = false; Invalidate(); } finally { loading = false; ResumeLayout(true); } }
private ArrowCrossings getCrossings() { float crad = flowChart.CrossingRadius; RectangleF rcArrow = getBoundingRect(); PointCollection intersections = new PointCollection(0); ArrowCrossings ac = (ArrowCrossings)getData(Constants.ARROW_CROSSINGS); if (ac == null) { ac = new ArrowCrossings(segmentCount); setData(Constants.ARROW_CROSSINGS, ac); // z index where this arrow is or will be placed int z = ZIndex; if (!constructed) z = flowChart.Objects.Count; // get the arrows which should be checked for intersections ArrowCollection arrows; if (flowChart.ArrowCrossings == MindFusion.FlowChartX.ArrowCrossings.Arcs) arrows = flowChart.getArrowsFromZ(true, z); else arrows = flowChart.getArrowsFromZ(false, z); // check each segment for (int sgt = 0; sgt < segmentCount; ++sgt) { PointF pt1 = Points[sgt]; PointF pt2 = Points[sgt+1]; if (pt1 == pt2) continue; // find intersecting points with each arrow for (int i = 0; i < arrows.Count; ++i) { Arrow arrow = arrows[i]; if (!arrow.Visible || arrow.Style == ArrowStyle.Bezier) continue; // dont check segments if arrow bounding rects dont intersect at all RectangleF rcTest = arrow.getBoundingRect(); if (!rcTest.IntersectsWith(rcArrow)) continue; for (int test = 0; test < arrow.SegmentCount; ++test) { PointF testPt1 = arrow.Points[test]; PointF testPt2 = arrow.Points[test+1]; if (testPt1 == testPt2) continue; PointF intersection = new PointF(0, 0); if (Utilities.segmentIntersect(pt1, pt2, testPt1, testPt2, ref intersection)) { if (Utilities.Distance(pt1, intersection) > crad && Utilities.Distance(pt2, intersection) > crad) intersections.Add(intersection); } } } // sort by distance to the first point intersections.Sort(new CloserDistance(pt1)); // add radial intersections to the runtime intersection data CloserDistance closer = new CloserDistance(pt1); PointCollection rintr = ac.segmentCrossings[sgt] as PointCollection; rintr.Add(pt1); for (int ptc = 0; ptc < intersections.Count; ++ptc) { PointF ptRes1, ptRes2, pt = intersections[ptc]; ptRes1 = ptRes2 = pt; RectangleF rc = RectangleF.FromLTRB( pt.X - crad, pt.Y - crad, pt.X + crad, pt.Y + crad); Utilities.getEllipseIntr(rc, pt1, pt, ref ptRes1); Utilities.getEllipseIntr(rc, pt2, pt, ref ptRes2); if (closer.Compare(ptRes1, ptRes2) < 0) { rintr.Add(ptRes1); rintr.Add(ptRes2); } else { rintr.Add(ptRes2); rintr.Add(ptRes1); } } rintr.Add(pt2); // Check if there are intersection that overlap for (int i = 1; i < rintr.Count - 2; ) { PointF p1 = rintr[i]; PointF p2 = rintr[i + 1]; if (closer.Compare(p1, p2) > 0 || Utilities.Distance(p1, p2) < Constants.getMillimeter(flowChart.MeasureUnit) / 2) { // Remove these points rintr.RemoveAt(i); rintr.RemoveAt(i); } else { i++; } } intersections.Clear(); } // for (int sgt = 0; sgt < GetSegments(); ++sgt) } return ac; }