private static void UpdateOldLineFigure(XmlDocument xmldoc, XmlNode node, string newType) { if (newType != null) node.Attributes["Type"].Value = newType; XmlNode lineSegmentNode = node.SelectSingleNode("LineSegment"); if (lineSegmentNode != null) { XmlAttribute pt1 = lineSegmentNode.Attributes["Pt1"]; XmlAttribute pt2 = lineSegmentNode.Attributes["Pt2"]; if (pt1 != null && pt2 != null) { XmlElement pointsNode = xmldoc.CreateElement(POLYLINE_ELE); DPoints pts = new DPoints(); pts.Add(DPoint.FromString(pt1.Value)); pts.Add(DPoint.FromString(pt2.Value)); XmlText txt = xmldoc.CreateTextNode(DPoints.FormatToString(pts)); pointsNode.AppendChild(txt); lineSegmentNode.AppendChild(pointsNode); } } }
public static void PreviewFigure(DEngine de, DTkViewer dv, Type figureClass, DAuthorProperties dap, DPoint viewerSize) { // add figure de so it shows on the viewer de.UndoRedo.Start("blah"); de.ClearPage(); Figure f = (Figure)Activator.CreateInstance(figureClass); dap.ApplyPropertiesToFigure(f); if (f is PolylineFigure) { DPoints pts = new DPoints(); pts.Add(new DPoint(viewerSize.X / 4.0, viewerSize.Y / 4.0)); pts.Add(new DPoint(viewerSize.X * 1.25 / 4.0, viewerSize.Y * 1.10 / 4.0)); pts.Add(new DPoint(viewerSize.X * 1.50 / 4.0, viewerSize.Y * 1.25 / 4.0)); pts.Add(new DPoint(viewerSize.X * 1.75 / 4.0, viewerSize.Y * 1.50 / 4.0)); pts.Add(new DPoint(viewerSize.X * 2.00 / 4.0, viewerSize.Y * 1.75 / 4.0)); pts.Add(new DPoint(viewerSize.X * 2.25 / 4.0, viewerSize.Y * 2.00 / 4.0)); pts.Add(new DPoint(viewerSize.X * 2.50 / 4.0, viewerSize.Y * 2.25 / 4.0)); pts.Add(new DPoint(viewerSize.X * 2.75 / 4.0, viewerSize.Y * 2.50 / 4.0)); pts.Add(new DPoint(viewerSize.X * 3 / 4.0, viewerSize.Y * 3 / 4.0)); ((PolylineFigure)f).Points = pts; } else if (f is ITextable) ((ITextable)f).Text = "Aa"; f.Left = viewerSize.X / 4.0; f.Top = viewerSize.Y / 4.0; f.Width = viewerSize.X / 2.0; f.Height = viewerSize.Y / 2.0; if (f is TextFigure) { f.Left = viewerSize.X / 8.0; f.Width = viewerSize.X * 3 / 4.0; } de.AddFigure(f); de.UndoRedo.Commit(); dv.Update(); }
DPoints GetPolyPoints(int num, bool join) { DPoints val = new DPoints(); for (int i = 0; i < num; i++) { // x proceeds y double x = GetInt16(), y = GetInt16(); WmfApplyTransforms(ref x, ref y); val.Add(new DPoint (x, y)); } // join polygon if (join && num > 1 && (val[0].X != val[num-1].X || val[0].Y != val[num-1].Y)) val.Add(val[0]); return val; }
private void PaintWmf(DGraphics dg) { dg.Save(); dg.Clip(Rect); // store current matrix DMatrix m = dg.SaveTransform(); // clear gdi objects WmfGdiObjects.Clear(); // check for placeable key if (WmfIsPlaceable) { bytesRead = 0; // read placeable header placeable = GetWmfPlaceable(); // checksum int sum = 0; for (int i = 0; i < (Marshal.SizeOf(typeof(Wmf.Placeable)) - 2 /* WmfPlaceable.Checksum is UInt16 */) / 2; i++) sum = sum ^ BitConverter.ToUInt16(ImageData, i * 2); if (sum != placeable.Checksum) System.Diagnostics.Debug.Fail("checksum failed"); // init matrix WmfUpdateMaxtrix(dg, m); // read header header = GetWmfHeader(); // iterate draw commands bool records = true; while (records) { int bytesReadPlusFuncHeaderSize = bytesRead; Wmf.FuncHeader fh = GetWmfFuncHeader(); bytesReadPlusFuncHeaderSize += (int)fh.Size * 2; bool breakme = false; switch (fh.Function) { case Wmf.SaveDC: break; case Wmf.CreatePalette: break; case Wmf.SetBkMode: int bkMode = GetInt16(); break; case Wmf.SetMapMode: int mapMode = GetInt16(); break; case Wmf.SetROP2: break; case Wmf.SetRelabs: break; case Wmf.SetPolyFillMode: int polyfillMode = GetInt16(); if (polyfillMode == Wmf.PfmAlernate) fillRule = DFillRule.EvenOdd; else fillRule = DFillRule.Winding; break; case Wmf.SetStretchBltMode: break; case Wmf.DeleteObject: WmfDeleteGdiObject(GetInt16()); break; case Wmf.RestoreDC: break; case Wmf.SelectObject: WmfSelectGdiObject(GetInt16()); break; case Wmf.SetTextAlign: break; case Wmf.SetBkColor: break; case Wmf.SetTextColor: break; case Wmf.SetWindowOrg: winY = GetInt16(); winX = GetInt16(); WmfUpdateMaxtrix(dg, m); break; case Wmf.SetWindowExt: winHeight = GetInt16(); winWidth = GetInt16(); WmfUpdateMaxtrix(dg, m); break; case Wmf.SetViewportOrg: viewY = GetInt16(); viewX = GetInt16(); //wmfUpdateMaxtrix(dg, m); break; case Wmf.SetViewportExt: viewHeight = GetInt16(); viewWidth = GetInt16(); //wmfUpdateMaxtrix(dg, m); break; case Wmf.LineTo: DPoint pt = GetPoint(); if (StrokeValid) dg.DrawLine(curPoint, pt, stroke, 1, strokeStyle, strokeWidth, strokeCap); curPoint = pt; break; case Wmf.MoveTo: curPoint = GetPoint(); break; case Wmf.SelectPalette: break; case Wmf.CreatePenIndirect: int gdiPenStyle = GetInt16(); int widthX = GetInt16(); int widthY = GetInt16(); DColor penColor = GetColor(); double penWidth = widthX; WmfApplyTransforms(ref penWidth); DStrokeStyle penStyle = DStrokeStyle.Solid; DStrokeCap penCap = DStrokeCap.Round; DStrokeJoin penJoin = DStrokeJoin.Round; if ((gdiPenStyle & Wmf.PS_DASHDOTDOT) == Wmf.PS_DASHDOTDOT) penStyle = DStrokeStyle.DashDotDot; else if ((gdiPenStyle & Wmf.PS_DASHDOT) == Wmf.PS_DASHDOT) penStyle = DStrokeStyle.DashDot; else if ((gdiPenStyle & Wmf.PS_DOT) == Wmf.PS_DOT) penStyle = DStrokeStyle.Dot; else if ((gdiPenStyle & Wmf.PS_DASH) == Wmf.PS_DASH) penStyle = DStrokeStyle.Dash; else penStyle = DStrokeStyle.Solid; if ((gdiPenStyle & Wmf.PS_ENDCAP_FLAT) == Wmf.PS_ENDCAP_FLAT) penCap = DStrokeCap.Butt; else if ((gdiPenStyle & Wmf.PS_ENDCAP_SQUARE) == Wmf.PS_ENDCAP_SQUARE) penCap = DStrokeCap.Square; else penCap = DStrokeCap.Round; if ((gdiPenStyle & Wmf.PS_JOIN_MITER) == Wmf.PS_JOIN_MITER) penJoin = DStrokeJoin.Mitre; else if ((gdiPenStyle & Wmf.PS_JOIN_BEVEL) == Wmf.PS_JOIN_BEVEL) penJoin = DStrokeJoin.Bevel; else penJoin = DStrokeJoin.Round; if ((gdiPenStyle & Wmf.PS_NULL) == Wmf.PS_NULL) WmfAddGdiObject(new WmfGdiPen(DColor.Empty, penWidth, penStyle, penCap, penJoin)); else WmfAddGdiObject(new WmfGdiPen(penColor, penWidth, penStyle, penCap, penJoin)); break; case Wmf.CreateFontIndirect: WmfAddGdiObject("font"); break; case Wmf.CreateBrushIndirect: int brushStyle = GetInt16(); DColor brushColor = GetColor(); int brushHatch = GetInt16(); if ((brushStyle & Wmf.BS_NULL) == Wmf.BS_NULL) WmfAddGdiObject(new WmfGdiBrush(DColor.Empty)); else WmfAddGdiObject(new WmfGdiBrush(brushColor)); break; case Wmf.Polygon: DPoints polygonPts = GetPolyPoints(GetInt16(), true); if (FillValid) dg.FillPolygon(polygonPts, fill, 1, fillRule); if (StrokeValid) dg.DrawPolyline(polygonPts, stroke, 1, strokeWidth, strokeStyle, strokeJoin, strokeCap); break; case Wmf.Polyline: DPoints polylinePts = GetPolyPoints(GetInt16(), false); if (StrokeValid) dg.DrawPolyline(polylinePts, stroke, 1, strokeWidth, strokeStyle, strokeJoin, strokeCap); break; case Wmf.Ellipse: goto case Wmf.Rectangle; case Wmf.Rectangle: DPoint br = GetPoint(); DPoint tl = GetPoint(); if (FillValid) { if (fh.Function == Wmf.Rectangle) dg.FillRect(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y, fill, 1); else if (fh.Function == Wmf.Ellipse) dg.FillEllipse(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y, fill, 1); } if (StrokeValid) { if (fh.Function == Wmf.Rectangle) dg.DrawRect(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y, stroke, 1, strokeWidth, strokeStyle, strokeJoin); else if (fh.Function == Wmf.Ellipse) dg.DrawEllipse(tl.X, tl.Y, br.X - tl.X, br.Y - tl.Y, stroke, 1, strokeWidth, strokeStyle); } break; case Wmf.PolyPolygon: // find out how many points int numPolygons = GetInt16(); int[] numPoints = new int[numPolygons]; for (int i = 0; i < numPolygons; i++) numPoints[i] = GetInt16(); // join polygons together DPoints polyPolyPoints = new DPoints(); for (int i = 0; i < numPolygons; i++) foreach (DPoint polyPolyPt in GetPolyPoints(numPoints[i], true)) polyPolyPoints.Add(polyPolyPt); // draw if (FillValid) dg.FillPolygon(polyPolyPoints, fill, 1, fillRule); if (StrokeValid) dg.DrawPolyline(polyPolyPoints, stroke, 1, strokeWidth, strokeStyle, strokeJoin, strokeCap); break; case Wmf.Escape: break; default: breakme = true; break; } if (bytesRead != bytesReadPlusFuncHeaderSize) bytesRead = bytesReadPlusFuncHeaderSize; if (breakme) break; } } dg.Restore(); }
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); } }
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; }
public static DPoints MarkerPoints(DMarker marker, DPoint center, double angle, double size) { double hsz = size / 2; DPoints pts = new DPoints(); DPoint pt; switch (marker) { case DMarker.Arrow: pt = DGeom.PointFromAngle(center, angle, hsz); pts.Add(pt); pt = DGeom.PointFromAngle(pt, angle + DGeom.HalfPi, hsz); pt = DGeom.PointFromAngle(pt, angle + Math.PI, size); pts.Add(pt); pt = DGeom.PointFromAngle(pt, angle - DGeom.HalfPi, size); pts.Add(pt); break; case DMarker.Dot: int n = (int)Math.Round(size); if (n < 4) n = 4; double angleSegment = (Math.PI * 2) / n; for (int i = 0; i < n; i++) pts.Add(DGeom.PointFromAngle(center, angle + angleSegment * i, hsz)); break; case DMarker.Square: pt = DGeom.PointFromAngle(center, angle, hsz); pt = DGeom.PointFromAngle(pt, angle + DGeom.HalfPi, hsz); pts.Add(pt); pt = DGeom.PointFromAngle(pt, angle + Math.PI, size); pts.Add(pt); pt = DGeom.PointFromAngle(pt, angle - DGeom.HalfPi, size); pts.Add(pt); pt = DGeom.PointFromAngle(pt, angle, size); pts.Add(pt); break; case DMarker.Diamond: pt = DGeom.PointFromAngle(center, angle, hsz); pts.Add(pt); pt = DGeom.PointFromAngle(pt, angle + DGeom.HalfPi, hsz); pt = DGeom.PointFromAngle(pt, angle + Math.PI, hsz); pts.Add(pt); pt = DGeom.PointFromAngle(pt, angle + Math.PI, hsz); pt = DGeom.PointFromAngle(pt, angle - DGeom.HalfPi, hsz); pts.Add(pt); pt = DGeom.PointFromAngle(pt, angle - DGeom.HalfPi, hsz); pt = DGeom.PointFromAngle(pt, angle, hsz); pts.Add(pt); break; } return pts; }
protected virtual void PaintContextHandle(DGraphics dg) { if (contextHandle) { double hb = _handleBorder * _controlScale; double hb2 = hb + hb; DRect r = GetContextHandleRect(); if (hb != 0) r = r.Resize(hb, hb, -hb2, -hb2); dg.FillEllipse(r, DColor.White); dg.DrawEllipse(r.X, r.Y, r.Width, r.Height, DColor.Black, 1, _controlScale, DStrokeStyle.Solid); double qW = r.Width / 4; double tH = r.Height / 3; DPoints pts = new DPoints(); pts.Add(new DPoint(r.X + qW, r.Y + tH)); pts.Add(new DPoint(r.X + qW * 2, r.Y + tH * 2)); pts.Add(new DPoint(r.X + qW * 3, r.Y + tH)); dg.DrawPolyline(pts, DColor.Black); } }
public LineFigure2(DPoint pt1, DPoint pt2) { DPoints pts = new DPoints(); pts.Add(pt1); pts.Add(pt2); Points = pts; }
void ResizePoints(double sX, double sY) { DPoints newPts = new DPoints(); foreach (DPoint pt in Points) { DPoint newPt = new DPoint(0, 0); if (sX == 1) newPt.X = pt.X; else newPt.X = pt.X + (pt.X - X) * (sX - 1); if (sY == 1) newPt.Y = pt.Y; else newPt.Y = pt.Y + (pt.Y - Y) * (sY - 1); newPts.Add(newPt); } Points = newPts; }
void MovePoints(double dX, double dY) { DPoints newPts = new DPoints(); foreach (DPoint pt in Points) newPts.Add(new DPoint(pt.X + dX, pt.Y + dY)); Points = newPts; }
DPoints DrawPoints() { DPoints pts = new DPoints(); foreach (DPoint pt in points) pts.Add(Vertex(pt)); // close the polygon pts.Add(pts[0]); // to draw the stroke join at the first vertex pts.Add(DGeom.PointFromAngle(pts[0], DGeom.AngleBetweenPoints(pts[0], pts[1]) - DGeom.HalfPi, 1)); // return new points return pts; }
public static DPoints SimplifyPolyline(DPoints original, double tolerance) { // using the Douglas-Peucker polyline simplification algorithm // see: http://geometryalgorithms.com/Archive/algorithm_0205/ // http://www.simdesign.nl/Components/DouglasPeucker.html if (original.Count <= 2) return original; // marker array bool[] markers = new bool[original.Count]; // include first and last point markers[0] = true; markers[original.Count - 1] = true; // exclude intermediate points for now for (int i = 1; i < original.Count - 2; i++) markers[i] = false; // Simplify SimplifyDP(original, tolerance, 0, original.Count - 1, markers); // return simplified polyline DPoints res = new DPoints(); for (int i = 0; i < original.Count; i++) if (markers[i]) res.Add(original[i]); return res; }