## Contents

This article describes a few steps to get embroided glyph. You can choose any glyph from any true type font and embroid it. Firstly, we need to extract glyph geometry from a true type font file. The second step is to produce zigzags on the glyph lines. Produced glyph zigzags look like the following:

After converting glyph zigzags to an embroidery format, such as DST, it could be embroided by embroidery machine on clothes.

This article is based on an idea of the ability to embroid any glyph of any true type font without any commercial software.

First of all, the .NET library `System.Windows.Media`

should be referenced in the project, and the following line should be added in the `namespace`

declaration of our file:

using System.Windows.Media;

True type font family file usually contains a single font family. Font family has a few typefaces.

According to MSDN, typeface represents a combination of FontFamily, FontWeight, FontStyle, and FontStretch.

Arial true type font, which is usually installed on Windows platform has nine typefaces:

Figure 1 - True type font variation

To get font families from a font file, we use method `GetFontFamilies`

of a `Fonts`

class from `System.Windows.Media`

namespace as follows:

ICollection<FontFamily> families = Fonts.GetFontFamilies(fontPath);

If we are in need of iterating through typefaces of a font family, we use a `GetTypefaces`

class of `FontFamily`

class from the same `namespace`

:

ICollection<Typeface> typefaces = fontFamily.GetTypefaces();

Instance of `Typeface`

class allows to create `GlyphTypeface`

instance:

GlyphTypeface glyph;
GlyphTypeface glyphTypeface = typeface.TryGetGlyphTypeface(out glyph) ? glyph : null;

When we have got an instance of `GlyphTypeface`

class, we can get the character map of a `typeface`

from its property `CharacterToGlyphMap`

. This property has type of `IDictionary<int, ushort>`

with unicode as key and glyph index as value.

To work with `glyph`

geometry, the class `GlyphTypeface`

is used. `Glyph`

geometry is obtained by its index:

Geometry geom = glyphTypeface.GetGlyphOutline(glyphIndex, renderingEmSize, hintingEmSize);

Although more often, we would like to get `glyph`

by its unicode number. So we get `glyph`

index from character map by its unicode number and then obtain `glyph`

geometry. In the method `GetGlyphOutline`

, three parameters are passed. The third parameter `hintingEmSize`

is discussed in detail here.

In the method `GetGlyphPoints()`

, an enumeration of `PointCollection`

is built on `PathGeometry`

instance, which is passed in `glyphGeom`

parameter. `PathGeometry`

instance of a glyph is obtained by the method `GetOutlinedPathGeometry()`

of `Geometry`

instance. Each collection of points in the enumeration represents a sequence of points for each figure in `PathGeometry`

. Which will be zigzagified in the next step.

public IEnumerable<PointCollection> GetGlyphPoints(PathGeometry glyphGeom)
{
var result = new List<PointCollection>();
PointCollection curColl = new PointCollection();
foreach (PathFigure figure in glyphGeom.Figures)
{
PointCollection flattenedShape = PathFigureFlattening.GetPathFigureFlattenedPoints(figure);
result.Add(flattenedShape);
}
return result;
}

Now we have sequences of points for specified glyph, and it can be converted to `SVG`

picture or just `JSON`

object. Although let's apply zigzagifying effect on this contour of the glyph. To do that, we need to split each intercept into small ones to provide zigzagifying by them.

In the following code of the `GetPointsOnLine()`

method, an axis direction is chosen by the longest axis delta of an itercept. It means, if delta `X`

is greater than delta Y, then the pass through `X`

axis and calculating delta `Y`

for each step by fixed increment value of `X`

is chosen. In case when delta `Y`

of intercept is greater than delta `X`

, it passes through `Y`

axis with fixed pitch. It allows to avoid deviation. The `length`

variable is calculated by the Pythagorean theorem formula:

The square of hypothenuse is equals to sum of cathetus squares.

By the `length`

and the `step`

value, the quantity of points on intercept is calculated. For short intercepts with less than six points, it sets the quantity of points to seven. It allows to build zigzag and leaves enough points to create curved zigzags with neighbor intercepts. It also checks for horizontal and vertical lines, there is a block of code to calculate point coordinates in this case. The method returns points as three list of coordinates: first two points, mid points, and last two points. Start point and end point are not included in the result. Mid points will be used for simple zigzagifying by finding perpendicular points to mid points of small interceptors. First two and last two will be used for finding points on curve to neighbor intercepts by Casteljau algorithm of finding points on curve, and then resolved sequence of points will be used to build zigzagified curve.

private List<List<DoubleVertice>> GetPointsOnLine(DoubleVertice start, DoubleVertice end, double step)
{
var result = new List<List<DoubleVertice>>();
var firstTwo = new List<DoubleVertice>();
var lastTwo = new List<DoubleVertice>();
var mediPoints = new List<DoubleVertice>();
double cathetusX;
double cathetusY;
double dx;
double dy;
GetDxDy(start, end, out cathetusX, out cathetusY);
double y0 = start.Y;
double y1 = end.Y;
double x0 = (double)start.X;
double x1 = (double)end.X;
double k;
bool shortLine = false;
double deltaX = 0.0;
double deltaY = 0.0;
int length = (int)Math.Sqrt(cathetusX * cathetusX + cathetusY * cathetusY);
int n = (int) Math.Sqrt((length*length)/(step*step));
if (ShortLineIterceptsCount - 1 > n)
{
n = ShortLineIterceptsCount;
shortLine = true;
dx = dx/ShortLineIterceptsCount;
dy = dy/ShortLineIterceptsCount;
}
else
{
var deltaVector = Get_qrtnDeltaVector(x0, y0, x1, y1, step);
dx = Math.Abs(deltaVector.X);
dy = Math.Abs(deltaVector.Y);
}
if (dy == 0 && dx == 0)
{
result.Add(new List<DoubleVertice> {start, end});
return result;
}
if (dy == 0 || dx == 0)
{
if (dy == 0)
{
deltaY = 0;
if (shortLine) step = dx;
if (x1 > x0) deltaX = step;
else deltaX = -step;
}
else if (dx == 0)
{
deltaX = 0;
if (shortLine) step = dy;
if (y1 > y0) deltaY = step;
else deltaY = -step;
}
}
else
{
if ((x0 < x1) && (y0 > y1))
{
deltaX = dx;
deltaY = -dy;
}
else if ((x0 > x1) && (y0 > y1))
{
deltaX = -dx;
deltaY = -dy;
}
else if ((x0 > x1) && (y0 < y1))
{
deltaX = -dx;
deltaY = dy;
}
else
{
deltaX = dx;
deltaY = dy;
}
}
double dX = (deltaX);
double dY = (deltaY);
deltaX = 0;
deltaY = 0;
double curX = x0, curY = y0;
if ((dx >= dy) && (dx != 0))
{
k = dY/dX;
for (var i = 0; (i < 2) && (dX != 0); i++)
{
deltaX += dX;
deltaY = (deltaX*k);
curX = x0 + deltaX;
curY = y0 + deltaY;
firstTwo.Add(new DoubleVertice {X = curX, Y = curY});
}
for (var i = 4; (i < n) && (dX != 0); i++)
{
curX = x0 + deltaX;
curY = y0 + deltaY;
mediPoints.Add(new DoubleVertice {X = curX, Y = curY});
deltaX += dX;
deltaY = (deltaX*k);
}
for (var i = 0; (i < 2) && (dX != 0); i++)
{
curX = x0 + deltaX;
curY = y0 + deltaY;
lastTwo.Add(new DoubleVertice {X = curX, Y = curY});
deltaX += dX;
deltaY = (deltaX*k);
}
}
else if (dy != 0)
{
k = dX/dY;
for (int i = 0; (i < 2) && (dY != 0); i++)
{
deltaX = (deltaY*k);
deltaY += dY;
curY = y0 + deltaY;
curX = x0 + deltaX;
firstTwo.Add(new DoubleVertice {X = curX, Y = curY});
}
for (int i = 4; (i < n) && (dY != 0); i++)
{
curY = y0 + deltaY;
curX = x0 + deltaX;
mediPoints.Add(new DoubleVertice {X = curX, Y = curY});
deltaX = (deltaY*k);
deltaY += dY;
}
for (int i = 0; (i < 2) && (dY != 0); i++)
{
curY = y0 + deltaY;
curX = x0 + deltaX;
lastTwo.Add(new DoubleVertice {X = curX, Y = curY});
deltaX = (deltaY*k);
deltaY += dY;
}
}
result.Add(firstTwo);
result.Add(mediPoints);
result.Add(lastTwo);
if (mediPoints.Count == 0)
{
Trace.WriteLine(string.Format("{0} {1}", start, end));
}
return result;
}

In the following picture, we have:

- neighbour step points of intercept
*A B* - mid point of intercept
*M* - points of zigzag to be found
*C D*

To find points of zigzags, the answer from stackoverflow was used. The solution is based on formula of equilaterial triangle height calculation. So coordinates of points C and D at figure 2 are calculated in the method `GetMediPerpendicularPoint(`

`)`

. Green dash line is our zigzag we are going to draw. Let's assume *C* is left point of zigzag. For point *C*, method is called with point *A* and *M* for `point0`

and `point1`

respectively. Parameter `opposite`

in this case is `false`

. So point *D* is right point of zigzag and `opposite`

is true. We pass points *M* and *D* as `point0`

and `point1`

for second zigzag point (*D*). To get all zigzags for whole intercept, we go through all mid points we get by `GetPointsOnLine()`

method.

Figure 2 - Perpendicular points detection

The normal of an equilateral triangle is the square root of three-quarters, so logic in the following method is based on this statement.

DoubleVertice GetMediPerpendicularPoint
(DoubleVertice point0, DoubleVertice point1, double distance, bool opposite)
{
double x, y, lx, ly, mx, my;
x = point1.X;
y = point1.Y;
lx = point0.X;
ly = point0.Y;
LineDirection direction;
double xPerpOffset = 0;
double yPerpOffset = 0;
var dx = x - lx;
var dy = y - ly;
mx = (lx + x) / 2;
my = (ly + y) / 2;
if (dx != 0.0 && dy != 0.0)
{
var scale = Math.Sqrt(0.75);
var dX = scale * (y - ly);
var dY = -scale * (x - lx);
var length = Math.Sqrt(dX * dX + dY * dY);
var xnorm = Math.Abs(dX / length);
var ynorm = Math.Abs(dY / length);
xPerpOffset = Math.Abs(xnorm * distance);
yPerpOffset = Math.Abs(ynorm * distance);
if ((x > lx) && (y > ly)) direction = LineDirection.UpRight;
else if ((x < lx) && (y < ly)) direction = LineDirection.DownLeft;
else if ((x > lx) && (y < ly)) direction = LineDirection.DownRight;
else direction = LineDirection.UpLeft;
switch (direction)
{
case LineDirection.UpRight:
if (opposite) yPerpOffset *= -1;
else xPerpOffset *= -1;
break;
case LineDirection.DownRight:
if (opposite)
{
yPerpOffset *= -1;
xPerpOffset *= -1;
}
break;
case LineDirection.DownLeft:
if (opposite) xPerpOffset *= -1;
else yPerpOffset *= -1;
break;
case LineDirection.UpLeft:
if (!opposite)
{
yPerpOffset *= -1;
xPerpOffset *= -1;
}
break;
}
}
else if (dx == 0.0)
{
yPerpOffset = 0.0;
if (ly < y)
{
xPerpOffset = distance * (opposite ? -1 : 1);
}
else
{
xPerpOffset = distance * (opposite ? 1 : -1);
}
}
else if (dy == 0.0)
{
xPerpOffset = 0.0;
if (lx < x)
{
yPerpOffset = distance * (opposite ? 1 : -1);
}
else
{
yPerpOffset = distance * (opposite ? -1 : 1);
}
}
return new DoubleVertice { X = mx + xPerpOffset, Y = my + yPerpOffset };
}

To get well rounded turns between intercepts, we add more mid points between second to last points of intercepts. Points are added by Casteljau algorithm. This is not the best way for this case, there are a few other ways, although for simple shapes, it works well. Interpretation of Casteljau algorithm adopted from a few CodeProject articles:

#region Casteljau DRAW METHOD
private List<DoubleVertice> casteljauPoints;
private List<DoubleVertice> drawCasteljau(List<DoubleVertice> list, double step)
{
casteljauPoints = list;
var result = new List<DoubleVertice>();
for (double t = 0; t <= 1; t += step)
{
DoubleVertice tmp = getCasteljauDoubleVertice(list.Count - 1, 0, t);
result.Add(tmp);
}
casteljauPoints.Clear();
return result;
}
private DoubleVertice getCasteljauDoubleVertice(int r, int i, double t)
{
if (r == 0) return casteljauPoints[i];
DoubleVertice p1 = getCasteljauDoubleVertice(r - 1, i, t);
DoubleVertice p2 = getCasteljauDoubleVertice(r - 1, i + 1, t);
return new DoubleVertice { X = ((1 - t) * p1.X + t * p2.X), Y = ((1 - t) * p1.Y + t * p2.Y) };
}
private IEnumerable<DoubleVertice> GetZigzagifiedTurn
(IEnumerable<DoubleVertice> vertices, double zigzagWidth, double step = 0.2)
{
var list = drawCasteljau(vertices.ToList(), step);
int pointCount = list.Count;
var result = new List<DoubleVertice>();
DoubleVertice prevVertex = list[0];
for (int i = 1; i < pointCount; i++)
{
var curVertex = list[i];
result.AddRange(GetZigzaggedBetweenTwoPoint(prevVertex, curVertex, zigzagWidth));
prevVertex = curVertex;
}
return result;
}
#endregion

How to convert sequence of points to Tajima DST format covered in an article.

Zigzagified glyph can be also converted to SVG with console application.

Now we have methods to get a sequence of points of any glyph from true type font file and can create zigzags on its lines. As was said, this way is not the best one. For more accurate drawing, there are another algorithms, which I did not find.

In the following figure is pictured zigzagified glyph in SVG format:

Figure 3 - One of webdings true type font glyphs.

Live example of glyph zigzagifying is here

You can download source code from here.

## Points of Interest

I would like slow drawing.

## History

- 12
^{th} January, 2016: Initial version