//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * * @param path * @param matrix * @param fillStyle * @param mode */ public void DrawPath(GraphicsPathFP path, MatrixFP matrix, BrushFP fs, int mode) { _transformMatrix = matrix; DrawPath(path, fs, mode); _transformMatrix = null; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Calculate outline with given pen. * @param lineStyle * @return */ public GraphicsPathFP CalcOutline(PenFP lineStyle) { var outline = new GraphicsPathFP(); var outlineGenerator = new GraphicsPathOutlineFP(outline, lineStyle); Visit(outlineGenerator); return(outline); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create the line path from given coordinates. * @param ff_x1 * @param ff_y1 * @param ff_x2 * @param ff_y2 * @return */ public static GraphicsPathFP CreateLine(int ffX1, int ffY1, int ffX2, int ffY2) { var path = new GraphicsPathFP(); path.AddMoveTo(new PointFP(ffX1, ffY1)); path.AddLineTo(new PointFP(ffX2, ffY2)); return(path); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create a smooth curve from given parameters. * @param points * @param offset * @param numberOfSegments * @param ff_factor * @param closed * @return */ public static GraphicsPathFP CreateSmoothCurves(PointFP[] points, int offset, int numberOfSegments, int ffFactor, bool closed) { var len = points.Length; var path = new GraphicsPathFP(); if (numberOfSegments < 1 || numberOfSegments > points.Length - 1 || offset < 0 || offset + numberOfSegments > len - 1) { return(path); } var pc1S = new PointFP[points.Length]; var pc2S = new PointFP[points.Length]; if (!closed) { pc1S[0] = points[0]; pc2S[len - 1] = points[len - 1]; } else { pc1S[0] = CalcControlPoint(points[len - 1], points[0], points[1], ffFactor); pc2S[0] = CalcControlPoint(points[1], points[0], points[len - 1], ffFactor); pc1S[len - 1] = CalcControlPoint(points[len - 2], points[len - 1], points[0], ffFactor); pc2S[len - 1] = CalcControlPoint(points[0], points[len - 1], points[len - 2], ffFactor); } for (var i = 1; i < len - 1; i++) { pc1S[i] = CalcControlPoint(points[i - 1], points[i], points[i + 1], ffFactor); pc2S[i] = CalcControlPoint(points[i + 1], points[i], points[i - 1], ffFactor); } path.AddMoveTo(points[offset]); for (var i = 0; i < numberOfSegments; i++) { path.AddCurveTo(pc1S[offset + i], pc2S[offset + i + 1], points[offset + i + 1]); } if (closed) { path.AddCurveTo(pc1S[len - 1], pc2S[0], points[0]); path.AddClose(); } return(path); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 09NOV2008 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create an round rectangle path from given parameter. * @param ff_xmin * @param ff_ymin * @param ff_xmax * @param ff_ymax * @param ff_rx * @param ff_ry * @return */ public static GraphicsPathFP CreateRoundRect(int ffXmin, int ffYmin, int ffXmax, int ffYmax, int ffRx, int ffRy) { const int ffPi = MathFP.PI; var path = new GraphicsPathFP(); path.AddMoveTo(new PointFP(ffXmin + ffRx, ffYmin)); path.AddLineTo(new PointFP(ffXmax - ffRx, ffYmin)); var ffRmax = MathFP.Min(ffXmax - ffXmin, ffYmax - ffYmin) / 2; if (ffRx > ffRmax) { ffRx = ffRmax; } if (ffRy > ffRmax) { ffRy = ffRmax; } if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmax - ffRx * 2, ffYmin, ffXmax, ffYmin + ffRy * 2, (-ffPi) / 2, 0, false, false)); } path.AddLineTo(new PointFP(ffXmax, ffYmin + ffRy)); path.AddLineTo(new PointFP(ffXmax, ffYmax - ffRy)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmax - ffRx * 2, ffYmax - ffRy * 2, ffXmax, ffYmax, 0, ffPi / 2, false, false)); } path.AddLineTo(new PointFP(ffXmax - ffRx, ffYmax)); path.AddLineTo(new PointFP(ffXmin + ffRx, ffYmax)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmin, ffYmax - ffRy * 2, ffXmin + ffRx * 2, ffYmax, ffPi / 2, ffPi, false, false)); } path.AddLineTo(new PointFP(ffXmin, ffYmax - ffRy)); path.AddLineTo(new PointFP(ffXmin, ffYmin + ffRy)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmin, ffYmin, ffXmin + ffRx * 2, ffYmin + ffRy * 2, -ffPi, (-ffPi) / 2, false, false)); } path.AddClose(); return(path); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Add a path to this path. * @param path */ public void AddPath(GraphicsPathFP path) { if (path._cmdsSize > 0) { ExtendIfNeeded(path._cmdsSize, path._pntsSize); Array.Copy(path._cmds, 0, _cmds, _cmdsSize, path._cmdsSize); for (int i = 0; i < path._pntsSize; i++) { _pnts[i + _pntsSize] = new PointFP(path._pnts[i]); } _cmdsSize += path._cmdsSize; _pntsSize += path._pntsSize; } }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * create a polyline path. * @param points * @return */ public static GraphicsPathFP CreatePolyline(PointFP[] points) { var path = new GraphicsPathFP(); if (points.Length > 0) { path.AddMoveTo(points[0]); for (var i = 1; i < points.Length; i++) { path.AddLineTo(points[i]); } } return(path); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Constructor. * @param from the path which need to be dashed. * @param dashArray the dash array. * @param offset from where the dash starts. */ public GraphicsPathDasherFP(GraphicsPathFP from, int[] dashArray, int offset) { _fromPath = new GraphicsPathFP(from); var arrayLength = dashArray.Length - offset; if (arrayLength > 1) { _pnts = new PointFP[BLOCKSIZE]; _cmds = new int[BLOCKSIZE]; _dashArray = new int[dashArray.Length - offset]; Array.Copy(dashArray, offset, _dashArray, 0, dashArray.Length); VisitPath(this); } }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * * @param path * @param style * @param mode */ public void DrawPath(GraphicsPathFP path, BrushFP style, int mode) { _scanIndex = 0; _drawMode = mode; path.Visit(this); RadixSort(Scanbuf, ScanbufTmp, _scanIndex); _fillStyle = style; if (_transformMatrix != null) { _fillStyle.SetGraphicsMatrix(_transformMatrix); } DrawBuffer(); _fillStyle = null; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Copy constructor. * @param from the one to be copied. */ public GraphicsPathFP(GraphicsPathFP from) { _cmdsSize = from._cmdsSize; _pntsSize = from._pntsSize; if (_cmdsSize > 0) { _cmds = new int[_cmdsSize]; _pnts = new PointFP[_pntsSize]; Array.Copy(from._cmds, 0, _cmds, 0, _cmdsSize); for (int i = 0; i < _pntsSize; i++) { _pnts[i] = new PointFP(from._pnts[i]); } } }
private void DashLine(GraphicsPathFP path, LineFP line) { if (_nextDistance < 0) { _nextDistance = _dashArray[_dashIndex]; _dashIndex = (_dashIndex + 1) % _dashArray.Length; } var distance = _nextDistance; var pt = line.GetPointAtDistance(distance); while (pt != null) { if (_isEmpty) { path.AddMoveTo(pt); } else { path.AddLineTo(pt); } _isEmpty = !_isEmpty; _nextDistance += _dashArray[_dashIndex]; distance = _nextDistance; pt = line.GetPointAtDistance(distance); _dashIndex = (_dashIndex + 1) % _dashArray.Length; } if (_isEmpty) { path.AddMoveTo(line.Pt2); } else { path.AddLineTo(line.Pt2); } _nextDistance = _nextDistance - line.GetLength(); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * return the dashed path, if the dash array is null, return the path * unchanged. * @return the dash path. */ public GraphicsPathFP GetDashedGraphicsPath() { if (_dashArray == null) { return(_fromPath); } var dashedPath = new GraphicsPathFP(); var lineFP = new LineFP(); var j = 0; for (var i = 0; i < _cmdsSize; i++) { switch (_cmds[i]) { case CMD_MOVETO: dashedPath.AddMoveTo(_pnts[j++]); break; case CMD_LINETO: { int pointIndex = j; lineFP.Reset(_pnts[pointIndex - 1], _pnts[pointIndex]); DashLine(dashedPath, lineFP); j++; } break; case CMD_CLOSE: dashedPath.AddClose(); break; } } return(dashedPath); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * return the dashed path, if the dash array is null, return the path * unchanged. * @return the dash path. */ public GraphicsPathFP GetDashedGraphicsPath() { if (_dashArray == null) { return _fromPath; } var dashedPath = new GraphicsPathFP(); var lineFP = new LineFP(); var j = 0; for (var i = 0; i < _cmdsSize; i++) { switch (_cmds[i]) { case CMD_MOVETO: dashedPath.AddMoveTo(_pnts[j++]); break; case CMD_LINETO: { int pointIndex = j; lineFP.Reset(_pnts[pointIndex - 1], _pnts[pointIndex]); DashLine(dashedPath, lineFP); j++; } break; case CMD_CLOSE: dashedPath.AddClose(); break; } } return dashedPath; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create arc path. * @param ff_xmin * @param ff_ymin * @param ff_xmax * @param ff_ymax * @param ff_startangle * @param ff_sweepangle * @param closed * @param standalone * @return */ public static GraphicsPathFP CreateArc(int ffXmin, int ffYmin, int ffXmax, int ffYmax, int ffStartangle, int ffSweepangle, bool closed, bool standalone) { if (ffSweepangle < 0) { ffStartangle += ffSweepangle; ffSweepangle = -ffSweepangle; } var segments = MathFP.Round(MathFP.Div(4 * MathFP.Abs(ffSweepangle), MathFP.PI)) >> SingleFP.DECIMAL_BITS; if (segments == 0) { segments = 1; } var path = new GraphicsPathFP(); var ffDarg = ffSweepangle / segments; var ffArg = ffStartangle; var ffLastcos = MathFP.Cos(ffStartangle); var ffLastsin = MathFP.Sin(ffStartangle); var ffXc = (ffXmin + ffXmax) / 2; var ffYc = (ffYmin + ffYmax) / 2; var ffRx = (ffXmax - ffXmin) / 2; var ffRy = (ffYmax - ffYmin) / 2; var ffRxbeta = MathFP.Mul(17381, ffRx); var ffRybeta = MathFP.Mul(17381, ffRy); if (closed) { path.AddMoveTo(new PointFP(ffXc, ffYc)); } for (var i = 1; i <= segments; i++) { ffArg = i == segments ? ffStartangle + ffSweepangle : ffArg + ffDarg; var ffCurrcos = MathFP.Cos(ffArg); var ffCurrsin = MathFP.Sin(ffArg); var ffX1 = ffXc + MathFP.Mul(ffRx, ffLastcos); var ffY1 = ffYc + MathFP.Mul(ffRy, ffLastsin); var ffX2 = ffXc + MathFP.Mul(ffRx, ffCurrcos); var ffY2 = ffYc + MathFP.Mul(ffRy, ffCurrsin); if (i == 1) { if (closed) { path.AddLineTo(new PointFP(ffX1, ffY1)); } else if (standalone) { path.AddMoveTo(new PointFP(ffX1, ffY1)); } } path.AddCurveTo( new PointFP(ffX1 - MathFP.Mul(ffRxbeta, ffLastsin), ffY1 + MathFP.Mul(ffRybeta, ffLastcos)), new PointFP(ffX2 + MathFP.Mul(ffRxbeta, ffCurrsin), ffY2 - MathFP.Mul(ffRybeta, ffCurrcos)), new PointFP(ffX2, ffY2)); ffLastcos = ffCurrcos; ffLastsin = ffCurrsin; } if (closed) { path.AddClose(); } return(path); }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create a smooth curve from given parameters. * @param points * @param offset * @param numberOfSegments * @param ff_factor * @param closed * @return */ public static GraphicsPathFP CreateSmoothCurves(PointFP[] points, int offset, int numberOfSegments, int ffFactor, bool closed) { var len = points.Length; var path = new GraphicsPathFP(); if (numberOfSegments < 1 || numberOfSegments > points.Length - 1 || offset < 0 || offset + numberOfSegments > len - 1) { return path; } var pc1S = new PointFP[points.Length]; var pc2S = new PointFP[points.Length]; if (!closed) { pc1S[0] = points[0]; pc2S[len - 1] = points[len - 1]; } else { pc1S[0] = CalcControlPoint(points[len - 1], points[0], points[1], ffFactor); pc2S[0] = CalcControlPoint(points[1], points[0], points[len - 1], ffFactor); pc1S[len - 1] = CalcControlPoint(points[len - 2], points[len - 1], points[0], ffFactor); pc2S[len - 1] = CalcControlPoint(points[0], points[len - 1], points[len - 2], ffFactor); } for (var i = 1; i < len - 1; i++) { pc1S[i] = CalcControlPoint(points[i - 1], points[i], points[i + 1], ffFactor); pc2S[i] = CalcControlPoint(points[i + 1], points[i], points[i - 1], ffFactor); } path.AddMoveTo(points[offset]); for (var i = 0; i < numberOfSegments; i++) { path.AddCurveTo(pc1S[offset + i], pc2S[offset + i + 1], points[offset + i + 1]); } if (closed) { path.AddCurveTo(pc1S[len - 1], pc2S[0], points[0]); path.AddClose(); } return path; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 09NOV2008 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create an round rectangle path from given parameter. * @param ff_xmin * @param ff_ymin * @param ff_xmax * @param ff_ymax * @param ff_rx * @param ff_ry * @return */ public static GraphicsPathFP CreateRoundRect(int ffXmin, int ffYmin, int ffXmax, int ffYmax, int ffRx, int ffRy) { const int ffPi = MathFP.PI; var path = new GraphicsPathFP(); path.AddMoveTo(new PointFP(ffXmin + ffRx, ffYmin)); path.AddLineTo(new PointFP(ffXmax - ffRx, ffYmin)); var ffRmax = MathFP.Min(ffXmax - ffXmin, ffYmax - ffYmin) / 2; if (ffRx > ffRmax) { ffRx = ffRmax; } if (ffRy > ffRmax) { ffRy = ffRmax; } if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmax - ffRx * 2, ffYmin, ffXmax, ffYmin + ffRy * 2, (-ffPi) / 2, 0, false, false)); } path.AddLineTo(new PointFP(ffXmax, ffYmin + ffRy)); path.AddLineTo(new PointFP(ffXmax, ffYmax - ffRy)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmax - ffRx * 2, ffYmax - ffRy * 2, ffXmax, ffYmax, 0, ffPi / 2, false, false)); } path.AddLineTo(new PointFP(ffXmax - ffRx, ffYmax)); path.AddLineTo(new PointFP(ffXmin + ffRx, ffYmax)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmin, ffYmax - ffRy * 2, ffXmin + ffRx * 2, ffYmax, ffPi / 2, ffPi, false, false)); } path.AddLineTo(new PointFP(ffXmin, ffYmax - ffRy)); path.AddLineTo(new PointFP(ffXmin, ffYmin + ffRy)); if (ffRx != 0 && ffRy != 0) { path.AddPath(CreateArc(ffXmin, ffYmin, ffXmin + ffRx * 2, ffYmin + ffRy * 2, -ffPi, (-ffPi) / 2, false, false)); } path.AddClose(); return path; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create the line path from given coordinates. * @param ff_x1 * @param ff_y1 * @param ff_x2 * @param ff_y2 * @return */ public static GraphicsPathFP CreateLine(int ffX1, int ffY1, int ffX2, int ffY2) { var path = new GraphicsPathFP(); path.AddMoveTo(new PointFP(ffX1, ffY1)); path.AddLineTo(new PointFP(ffX2, ffY2)); return path; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Create arc path. * @param ff_xmin * @param ff_ymin * @param ff_xmax * @param ff_ymax * @param ff_startangle * @param ff_sweepangle * @param closed * @param standalone * @return */ public static GraphicsPathFP CreateArc(int ffXmin, int ffYmin, int ffXmax, int ffYmax, int ffStartangle, int ffSweepangle, bool closed, bool standalone) { if (ffSweepangle < 0) { ffStartangle += ffSweepangle; ffSweepangle = -ffSweepangle; } var segments = MathFP.Round(MathFP.Div(4 * MathFP.Abs(ffSweepangle), MathFP.PI)) >> SingleFP.DECIMAL_BITS; if (segments == 0) { segments = 1; } var path = new GraphicsPathFP(); var ffDarg = ffSweepangle / segments; var ffArg = ffStartangle; var ffLastcos = MathFP.Cos(ffStartangle); var ffLastsin = MathFP.Sin(ffStartangle); var ffXc = (ffXmin + ffXmax) / 2; var ffYc = (ffYmin + ffYmax) / 2; var ffRx = (ffXmax - ffXmin) / 2; var ffRy = (ffYmax - ffYmin) / 2; var ffRxbeta = MathFP.Mul(17381, ffRx); var ffRybeta = MathFP.Mul(17381, ffRy); if (closed) { path.AddMoveTo(new PointFP(ffXc, ffYc)); } for (var i = 1; i <= segments; i++) { ffArg = i == segments ? ffStartangle + ffSweepangle : ffArg + ffDarg; var ffCurrcos = MathFP.Cos(ffArg); var ffCurrsin = MathFP.Sin(ffArg); var ffX1 = ffXc + MathFP.Mul(ffRx, ffLastcos); var ffY1 = ffYc + MathFP.Mul(ffRy, ffLastsin); var ffX2 = ffXc + MathFP.Mul(ffRx, ffCurrcos); var ffY2 = ffYc + MathFP.Mul(ffRy, ffCurrsin); if (i == 1) { if (closed) { path.AddLineTo(new PointFP(ffX1, ffY1)); } else if (standalone) { path.AddMoveTo(new PointFP(ffX1, ffY1)); } } path.AddCurveTo( new PointFP(ffX1 - MathFP.Mul(ffRxbeta, ffLastsin), ffY1 + MathFP.Mul(ffRybeta, ffLastcos)), new PointFP(ffX2 + MathFP.Mul(ffRxbeta, ffCurrsin), ffY2 - MathFP.Mul(ffRybeta, ffCurrcos)), new PointFP(ffX2, ffY2)); ffLastcos = ffCurrcos; ffLastsin = ffCurrsin; } if (closed) { path.AddClose(); } return path; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * Calculate outline with given pen. * @param lineStyle * @return */ public GraphicsPathFP CalcOutline(PenFP lineStyle) { var outline = new GraphicsPathFP(); var outlineGenerator = new GraphicsPathOutlineFP(outline, lineStyle); Visit(outlineGenerator); return outline; }
//////////////////////////////////////////////////////////////////////////// //--------------------------------- REVISIONS ------------------------------ // Date Name Tracking # Description // --------- ------------------- ------------- ---------------------- // 13JUN2009 James Shen Initial Creation //////////////////////////////////////////////////////////////////////////// /** * create a polyline path. * @param points * @return */ public static GraphicsPathFP CreatePolyline(PointFP[] points) { var path = new GraphicsPathFP(); if (points.Length > 0) { path.AddMoveTo(points[0]); for (var i = 1; i < points.Length; i++) { path.AddLineTo(points[i]); } } return path; }