public PathStatistics(PathData data) { _data = data; int i = 1; _totalLength = 0; ISegment newSegment; while (i < _data.Points.Length) { switch (_data.Types[i]) { case 1: newSegment = new LineSegment(_data.Points[i - 1], _data.Points[i]); i++; break; case 3: newSegment = new CubicBezierSegment(_data.Points[i - 1], _data.Points[i], _data.Points[i + 1], _data.Points[i + 2]); i+= 3; break; default: throw new NotSupportedException(); } newSegment.StartOffset = _totalLength; _segments.Add(newSegment); _totalLength += newSegment.Length; } }
public void SetData(string c,PathData pd,RectangleF rect) { this.character = c; this.points = pd.Points; this.pointTypes = pd.Types; this.size = new SizeF(rect.Width, rect.Height); }
public void PathData_LengthMismatch () { PathData data = new PathData (); data.Points = new PointF[2]; data.Types = new byte[1]; Assert.AreEqual (2, data.Points.Length, "Points-2"); Assert.AreEqual (1, data.Types.Length, "Types-1"); }
public void PathData_UnclonedProperties () { PathData data = new PathData (); data.Points = new PointF[1] { new PointF (1f, 1f) }; data.Types = new byte[1] { 1 }; Assert.AreEqual (1f, data.Points[0].X, "Points.X"); Assert.AreEqual (1f, data.Points[0].Y, "Points.Y"); Assert.AreEqual (1, data.Types[0], "Types"); data.Points[0] = new PointF (0f, 0f); Assert.AreEqual (0f, data.Points[0].X, "Points.X.1"); Assert.AreEqual (0f, data.Points[0].Y, "Points.Y.1"); data.Types[0] = 0; Assert.AreEqual (0, data.Types[0], "Types-1"); }
public void PathData_Empty () { PathData data = new PathData (); Assert.IsNull (data.Points, "Points"); Assert.IsNull (data.Types, "Types"); data.Points = new PointF[0]; data.Types = new byte[0]; Assert.AreEqual (0, data.Points.Length, "Points-0"); Assert.AreEqual (0, data.Types.Length, "Types-0"); data.Points = null; data.Types = null; Assert.IsNull (data.Points, "Points-1"); Assert.IsNull (data.Types, "Types-1"); }
static public bool DrawGraphicsPath( System.Drawing.Graphics pGraphics, System.Drawing.Drawing2D.GraphicsPath pGraphicsPath, System.Drawing.Color clrPen, float fPenWidth) { if (pGraphics == null || pGraphicsPath == null) { return(false); } System.Drawing.Drawing2D.PathData pathData = pGraphicsPath.PathData; if (pathData.Points.Length <= 0) { return(false); } System.Drawing.Pen pen = new Pen(clrPen, fPenWidth); pen.LineJoin = LineJoin.Round; stBezier bezier = new stBezier(); stStart start = new stStart(); PointF prevPoint = new PointF(); for (int i = 0; i < pathData.Types.Length; ++i) { byte maskedByte = pathData.Types[i]; if (pathData.Types[i] == (byte)PathPointType.PathTypeMask) { maskedByte = (byte)(pathData.Types[i] & 0x3); } switch (maskedByte) { case PathPointType.Start: case PathPointType.Start | PathPointType.PathMarker: start.fPoint = pathData.Points[i]; start.nCount = 1; start.bDrawn = false; bezier.nCount = 0; break; case PathPointType.Line: case PathPointType.Line | PathPointType.PathMarker: pGraphics.DrawLine(pen, prevPoint, pathData.Points[i]); break; case PathPointType.Line | PathPointType.CloseSubpath: case PathPointType.Line | PathPointType.PathMarker | PathPointType.CloseSubpath: pGraphics.DrawLine(pen, prevPoint, pathData.Points[i]); pGraphics.DrawLine(pen, pathData.Points[i], start.fPoint); start.nCount = 0; break; case PathPointType.Bezier: case PathPointType.Bezier | PathPointType.PathMarker: bezier.fPoints[bezier.nCount] = pathData.Points[i]; bezier.nCount++; if (bezier.nCount == 1) { pGraphics.DrawLine(pen, prevPoint, pathData.Points[i]); } if (bezier.nCount >= 4) { pGraphics.DrawBezier(pen, bezier.fPoints[0], bezier.fPoints[1], bezier.fPoints[2], bezier.fPoints[3]); bezier.nCount = 0; } break; case PathPointType.Bezier | PathPointType.CloseSubpath: case PathPointType.Bezier | PathPointType.PathMarker | PathPointType.CloseSubpath: bezier.fPoints[bezier.nCount] = pathData.Points[i]; bezier.nCount++; if (bezier.nCount == 1) { pGraphics.DrawLine(pen, prevPoint, pathData.Points[i]); } if (bezier.nCount >= 4) { pGraphics.DrawBezier(pen, bezier.fPoints[0], bezier.fPoints[1], bezier.fPoints[2], bezier.fPoints[3]); bezier.nCount = 0; if (start.nCount == 1) { pGraphics.DrawLine(pen, pathData.Points[i], start.fPoint); start.nCount = 0; } } else if (start.nCount == 1) { pGraphics.DrawLine(pen, pathData.Points[i], start.fPoint); start.nCount = 0; start.bDrawn = true; } break; default: { //wchar_t buf[200]; //memset(buf,0, sizeof(buf)); //wsprintf(buf,_T("maskedByte: 0x%X\n"), maskedByte); //OutputDebugStringW(buf); } break; } prevPoint = pathData.Points[i]; } return(true); }
private void ClearCache () { _pathData = null; _generalPath = null; }
private PathData GetPathData () { PathData pathData = new PathData(); int nPts = PointCount; for (int i = 0; i < TypesCount; i++) if ((Types [i] & SEG_MASK) == SEG_QUADTO) nPts++; pathData.Types = new byte [nPts]; pathData.Points = new PointF [nPts]; int tpos = 0; int ppos = 0; int cpos = 0; byte marker; bool start; for (int i = 0; i < TypesCount; i++) { sbyte segmentType = (sbyte)(Types [i] & SEG_MASK); // set the masks and the markers marker = ((Types [i] & SEG_MARKER) != 0) ? (byte)PathPointType.PathMarker : (byte)0; start = ((Types [i] & SEG_START) != 0); switch (segmentType) { case SEG_CLOSE: pathData.Types [tpos - 1] = (byte) (pathData.Types [tpos - 1] | (byte) PathPointType.CloseSubpath | marker); break; case SEG_MOVETO: pathData.Types [tpos++] = (byte)((byte) PathPointType.Start | marker); pathData.Points [ppos++] = new PointF (Coords [cpos++], Coords [cpos++]); break; case SEG_LINETO: pathData.Types [tpos++] = (byte) ((byte) PathPointType.Line | marker); pathData.Points [ppos++] = new PointF (Coords [cpos++], Coords [cpos++]); break; case SEG_QUADTO: /* .net does not support Quadratic curves, so convert to Cubic according to http://pfaedit.sourceforge.net/bezier.html The end points of the cubic will be the same as the quadratic's. CP0 = QP0 CP3 = QP2 The two control points for the cubic are: CP1 = QP0 + 2/3 *(QP1-QP0) CP2 = CP1 + 1/3 *(QP2-QP0) */ float x0 = Coords[cpos-2]; //QP0 float y0 = Coords[cpos-1]; //QP0 float x1 = x0 + (2/3 * (Coords [cpos++]-x0)); float y1 = y0 + (2/3 * (Coords [cpos++]-y0)); float x3 = Coords [cpos++]; //QP2 float y3 = Coords [cpos++]; //QP2 float x2 = x1 + (1/3 * (x3-x0)); float y2 = y1 + (1/3 * (y3-y0)); pathData.Types [tpos++] = (byte)(byte) PathPointType.Bezier; pathData.Points [ppos++] = new PointF (x1, y1); pathData.Types [tpos++] = (byte)(byte) PathPointType.Bezier; pathData.Points [ppos++] = new PointF (x2, y2); pathData.Types [tpos++] = (byte) ((byte)PathPointType.Bezier | marker); pathData.Points [ppos++] = new PointF (x3, y3); break; case SEG_CUBICTO: pathData.Types [tpos++] = (byte)(byte) PathPointType.Bezier3; pathData.Points [ppos++] = new PointF (Coords [cpos++], Coords [cpos++]); pathData.Types [tpos++] = (byte) PathPointType.Bezier3; pathData.Points [ppos++] = new PointF (Coords [cpos++], Coords [cpos++]); pathData.Types [tpos++] = (byte) ((byte)PathPointType.Bezier3 | marker); pathData.Points [ppos++] = new PointF (Coords [cpos++], Coords [cpos++]); break; } } return pathData; }
private string ExtractPolygonImplementation(PathData pathData) { //Check if path is valid if (! mIsPolygon) { if (! IsPathPolygonImplementation(mPath)) throw new Exception("The path cannot be converted to an SVG polygon"); } StringBuilder def = new StringBuilder(); int i = 0; def.Append("<polygon "); if (IncludeId) def.Append("id=\"\" "); def.Append("points=\""); for (i = 0; i <= pathData.Points.GetUpperBound(0); i++) { def.Append(XmlConvert.ToString(Math.Round(pathData.Points[i].X, 2))); def.Append(","); def.Append(XmlConvert.ToString(Math.Round(pathData.Points[i].Y, 2))); def.Append(" "); } def.Append("\"/>"); return def.ToString(); }
//Extracts a path from a valid gdi path")] private string ExtractPathImplementation(PathData pathData) { StringBuilder def = new StringBuilder(); int i = 0; byte bytType; int cCount = 0; string strX = null; string strY = null; def.Append("<path "); if (IncludeId) def.Append("id=\"\" "); def.Append("fill-rule=\"evenodd\" d=\""); for (i = 0; i <= pathData.Points.GetUpperBound(0); i++) { bytType = pathData.Types[i]; strX = XmlConvert.ToString(Math.Round(pathData.Points[i].X, 2)); strY = XmlConvert.ToString(Math.Round(pathData.Points[i].Y, 2)); if (bytType == 0) //Moveto { def.Append("M "); def.Append(strX); def.Append(","); def.Append(strY); def.Append(" "); cCount = 0; } else { if (bytType == 1) //Lineto { def.Append("L "); def.Append(strX); def.Append(","); def.Append(strY); def.Append(" "); cCount = 0; } else { if (bytType > 128) //lineto or curve and closepath { if (cCount == 0) { def.Append("L "); } def.Append(strX); def.Append(","); def.Append(strY); def.Append(" Z "); cCount = 0; } else { if (cCount == 0) //Curve, in groups of 3 { def.Append("C "); } def.Append(strX); def.Append(","); def.Append(strY); def.Append(" "); cCount += 1; if (cCount == 3) { cCount = 0; } } } } } def.Append("\"/>"); return def.ToString(); }
public void DrawTextOnPath(PathData pathdata, string text, Font font, Color color, Brush fillcolor, int letterspacepercentage, int vOffset) { _pathdata = pathdata; _text = text; _font = font; _color = color; _fillBrush = fillcolor; _letterspacepercentage = letterspacepercentage; VerticalOffset = vOffset; DrawTextOnPath(); }
//Extracts an ellipse from a valid path." private string ExtractEllipseImplementation(PathData pathData) { //Check if path is valid if (! mIsEllipse) { if (! IsPathEllipseImplementation(mPath)) throw new Exception("The path cannot be converted to an SVG ellipse"); } StringBuilder def = new StringBuilder(); def.Append("<ellipse "); if (IncludeId) def.Append("id=\"\" "); def.Append("cx=\""); def.Append(XmlConvert.ToString(pathData.Points[3].X)); def.Append("\" cy=\""); def.Append(XmlConvert.ToString(pathData.Points[0].Y)); def.Append("\" rx=\""); def.Append(XmlConvert.ToString(pathData.Points[3].X)); def.Append("\" ry=\""); def.Append(XmlConvert.ToString(pathData.Points[0].Y)); def.Append("\"/>"); return def.ToString(); }
void DumpPathData(PathData pathData) { XPoint[] points = new XPoint[pathData.Points.Length]; for (int i = 0; i < points.Length; i++) points[i] = new XPoint(pathData.Points[i].X, pathData.Points[i].Y); DumpPathData(points, pathData.Types); }
/// <summary> /// /// </summary> /// <param name="pathdata">The path data</param> /// <param name="text">The text</param> /// <param name="font">The font</param> /// <param name="haloPen">The halo pen</param> /// <param name="fillcolor">The brush to fill letters</param> /// <param name="letterspacepercentage">The </param> public void DrawTextOnPath(PathData pathdata, string text, Font font, Pen haloPen, Brush fillcolor, int letterspacepercentage) { _pathdata = pathdata; Text = text; _font = font; _colorHalo= haloPen; _fillBrush = fillcolor; _letterspacepercentage = letterspacepercentage / 100d; DrawTextOnPath(); }
internal void DrawTextOnPath(PathData pathdata, string text, Font font, Color color, Brush fillcolor, int letterspacepercentage) { _pathdata = pathdata; _text = text; _font = font; _color = color; _fillBrush = fillcolor; _letterspacepercentage = letterspacepercentage; DrawTextOnPath(); }
public static void ConvertToVxs(System.Drawing.Drawing2D.PathData pathdata, VertexStore outputVxs) { byte[] pointTypes = pathdata.Types; PointF[] points = pathdata.Points; int pointCount = points.Length; //from MSDN document //0 = start of figure (MoveTo) //1 = one of the two endpoints of a line (LineTo) //3 = an endpoint or control point of a cubic Bezier spline (4 points spline) //masks.. //0x7 = 111b (binary) => for masking lower 3 bits //0x20 = (1<<6) specific that point is a marker //0x80 = (1<<7) specific that point is the last point of a closed subpath( figure) //---------------------------------- //convert to Agg's VertexStorage int curvePointCount = 0; for (int i = 0; i < pointCount; ++i) { byte pointType = pointTypes[i]; PointF p = points[i]; switch (0x7 & pointType) { case 0: //move to outputVxs.AddMoveTo(p.X, p.Y); curvePointCount = 0; break; case 1: //line to outputVxs.AddLineTo(p.X, p.Y); curvePointCount = 0; break; case 3: //end point of control point of cubic Bezier spline { switch (curvePointCount) { case 0: { outputVxs.AddP2c(p.X, p.Y); curvePointCount++; } break; case 1: { outputVxs.AddP3c(p.X, p.Y); curvePointCount++; } break; case 2: { outputVxs.AddLineTo(p.X, p.Y); curvePointCount = 0; //reset } break; default: { throw new NotSupportedException(); } } } break; default: { } break; } if ((pointType >> 7) == 1) { //close figure to outputVxs.AddCloseFigure(); } if ((pointType >> 6) == 1) { } } }
private PathData _GetPathData() { int ptSize = (int) Marshal.SizeOf(typeof(GPPOINTF)); int numPts = PointCount; PathData pathData = new PathData(); pathData.Types = new byte[numPts]; IntPtr memoryPathData = Marshal.AllocHGlobal(3*IntPtr.Size); IntPtr memoryPoints = Marshal.AllocHGlobal(checked(ptSize*numPts)); try { GCHandle typesHandle = GCHandle.Alloc(pathData.Types, GCHandleType.Pinned); try { IntPtr typesPtr = typesHandle.AddrOfPinnedObject(); //IntPtr typesPtr = Marshal.AddrOfArrayElement(pathData.Types, IntPtr.Zero); Marshal.StructureToPtr(numPts, memoryPathData, false); Marshal.StructureToPtr(memoryPoints, (IntPtr)((long)memoryPathData+IntPtr.Size), false); Marshal.StructureToPtr(typesPtr, (IntPtr)((long)memoryPathData+2*IntPtr.Size), false); int status = SafeNativeMethods.Gdip.GdipGetPathData(new HandleRef(this, nativePath), memoryPathData); if (status != SafeNativeMethods.Gdip.Ok) { throw SafeNativeMethods.Gdip.StatusException(status); } pathData.Points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(memoryPoints, numPts); } finally { typesHandle.Free(); } } finally { Marshal.FreeHGlobal(memoryPathData); Marshal.FreeHGlobal(memoryPoints); } return pathData; }