Merge pull request #13 from terryspitz/master

Add helpers which return raw SpiroSegment arrays
This commit is contained in:
Wiesław Šoltés 2020-03-29 14:00:43 +02:00 коммит произвёл GitHub
Родитель 365b3a35e0 b365a1048c
Коммит b17de94a20
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 130 добавлений и 42 удалений

Просмотреть файл

@ -72,6 +72,54 @@ namespace SpiroNet
TaggedSpiroCPsToBezier0(spiros, bc);
}
/// <summary>
/// Convert a set of spiro control points into a set of bézier curves.
///
/// As it does so it will call the appropriate routine in your bézier context with this information
/// – this should allow you to create your own internal representation of those curves.
///
/// Open contours do not need to start with '{', nor to end with '}'.
///
/// Close contours do not need to end with 'z'.
///
/// This function is kept for backwards compatibility for older programs.
/// Please use the function that return success/failure replies when done.
/// </summary>
/// <param name="spiros">An array of input spiros.</param>
/// <param name="n">The number of elements in the spiros array.</param>
/// <param name="isClosed">Whether this describes a closed (True) or open (False) contour.</param>
/// <returns>SpiroSegment array or null on failure.</returns>
/// <example>
/// var points = new SpiroControlPoint[4];
/// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
/// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
/// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
/// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
/// var bc = new PathBezierContext();
/// var success = Spiro.SpiroCPsToBezier0(points, 4, true, bc);
/// Console.WriteLine(bc);
/// Console.WriteLine("Success: {0} ", success);
/// </example>
public static SpiroSegment[]? SpiroCPsToSegments(SpiroControlPoint[] spiros, int n, bool isClosed)
{
if (n <= 0)
return null;
if (isClosed)
return SpiroImpl.run_spiro(spiros, n);
else
{
SpiroPointType oldty_start = spiros[0].Type;
SpiroPointType oldty_end = spiros[n - 1].Type;
spiros[0].Type = SpiroPointType.OpenContour;
spiros[n - 1].Type = SpiroPointType.EndOpenContour;
SpiroSegment[]? s;
s = SpiroImpl.run_spiro(spiros, n);
spiros[n - 1].Type = oldty_end;
spiros[0].Type = oldty_start;
return s;
}
}
/// <summary>
/// Convert a set of spiro control points into a set of bézier curves.
///
@ -103,23 +151,7 @@ namespace SpiroNet
/// </example>
public static bool SpiroCPsToBezier0(SpiroControlPoint[] spiros, int n, bool isClosed, IBezierContext bc)
{
SpiroSegment[]? s;
if (n <= 0)
return false;
if (isClosed)
s = SpiroImpl.run_spiro(spiros, n);
else
{
SpiroPointType oldty_start = spiros[0].Type;
SpiroPointType oldty_end = spiros[n - 1].Type;
spiros[0].Type = SpiroPointType.OpenContour;
spiros[n - 1].Type = SpiroPointType.EndOpenContour;
s = SpiroImpl.run_spiro(spiros, n);
spiros[n - 1].Type = oldty_end;
spiros[0].Type = oldty_start;
}
SpiroSegment[]? s = SpiroCPsToSegments(spiros, n, isClosed);
if (s != null)
{
SpiroImpl.spiro_to_bpath(s, n, bc);
@ -129,6 +161,68 @@ namespace SpiroNet
return false; // spiro did not converge or encountered non-finite values
}
/// <summary>
/// Convert a tagged set of spiro control points into a set of bézier curves.
///
/// As it does so it will call the appropriate routine in your bézier context with this information
/// – this should allow you to create your own internal representation of those curves.
///
/// The spiros array should indicate it's own end.
///
/// Open contours must have the ty field of the first cp set to '{' and have the ty field of the last cp set to '}'.
///
/// Closed contours must have an extra cp at the end whose ty is 'z' the x and y values of this extra cp are ignored.
/// </summary>
/// <param name="spiros">An array of input spiros.</param>
/// <returns>SpiroSegment array or null on failure.</returns>
/// <example>
/// var points = new SpiroControlPoint[5];
/// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
/// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
/// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
/// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
/// points[4].X = 0; points[4].Y = 0; points[4].Type = SpiroPointType.End;
/// var bc = new PathBezierContext();
/// var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
/// Console.WriteLine(bc);
/// Console.WriteLine("Success: {0} ", success);
///
/// var points = new SpiroControlPoint[5];
/// points[0].X = -100; points[0].Y = 0; points[0].Type = SpiroPointType.G4;
/// points[1].X = 0; points[1].Y = 100; points[1].Type = SpiroPointType.G4;
/// points[2].X = 100; points[2].Y = 0; points[2].Type = SpiroPointType.G4;
/// points[3].X = 0; points[3].Y = -100; points[3].Type = SpiroPointType.G4;
/// points[4].X = 0; points[4].Y = 0; points[4].Type = SpiroPointType.End;
/// var bc = new PathBezierContext();
/// var success = Spiro.TaggedSpiroCPsToBezier0(points, bc);
/// Console.WriteLine(bc);
/// Console.WriteLine("Success: {0} ", success);
/// </example>
public static SpiroSegment[]? TaggedSpiroCPsToSegments(SpiroControlPoint[] spiros)
{
if(spiros.Length == 0) return null;
int n = 0;
while (true)
{
if (spiros[n].Type == SpiroPointType.End || spiros[n].Type == SpiroPointType.EndOpenContour)
break;
// invalid input
if (n >= spiros.Length)
return null;
++n;
}
if (spiros[n].Type == SpiroPointType.EndOpenContour)
++n;
if (n <= 0)
return null; // invalid input
return SpiroImpl.run_spiro(spiros, n);
}
/// <summary>
/// Convert a tagged set of spiro control points into a set of bézier curves.
///
@ -169,33 +263,10 @@ namespace SpiroNet
/// </example>
public static bool TaggedSpiroCPsToBezier0(SpiroControlPoint[] spiros, IBezierContext bc)
{
SpiroSegment[]? s;
int n;
n = 0;
while (true)
{
if (spiros[n].Type == SpiroPointType.End || spiros[n].Type == SpiroPointType.EndOpenContour)
break;
// invalid input
if (n >= spiros.Length)
return false;
++n;
}
if (spiros[n].Type == SpiroPointType.EndOpenContour)
++n;
if (n <= 0)
return false; // invalid input
s = SpiroImpl.run_spiro(spiros, n);
var s = TaggedSpiroCPsToSegments(spiros);
if (s != null)
{
SpiroImpl.spiro_to_bpath(s, n, bc);
SpiroImpl.spiro_to_bpath(s, s.Length-1, bc);
return true; // success
}

Просмотреть файл

@ -41,5 +41,13 @@ namespace SpiroNet
/// Spiro code point Type.
/// </summary>
public SpiroPointType Type;
/// <summary>
/// Returns string rendering of object.
/// </summary>
public override string ToString()
{
return X.ToString() + ", " + Y.ToString() + ", " + Type.ToString();
}
}
}

Просмотреть файл

@ -68,5 +68,14 @@ namespace SpiroNet
/// Unused.
/// </summary>
public double l;
/// <summary>
/// Returns string rendering of object.
/// </summary>
public override string ToString()
{
return X.ToString() + ", " + Y.ToString() + ", " + Type.ToString() + " (" +
seg_th.ToString() + ")";
}
}
}