Skip to content

Linetype Variations Specification

Karl R. Wilcox edited this page Mar 9, 2021 · 6 revisions

So now we have our shape specification, we need to turn this into an SVG path, based on the set of vector directions we have been given and a description of the type of edge (plain, wavy, arched, etc).

The Edge Variant Specification

(In the discussion below, I try to use the term "edge" to mean one of the vectors from the Shape Specification and "linetype" to mean the pattern shown along that edge.)

Here are some examples of variant linetypes:

Linetype Name Example
Wavy Wavy
Angled Angled
Arched Arched
Nowy Nowy
Escartelly Escartelly

The shape specification above gives us an overall shape made up of edges, but we now need to draw that shape with the edges replaced by the give linetype, with the end result being an SVG path.

Each of the linetype variations is provided as a linetype specification. Before I explain this, let us first note that there are different categories of linetype:

  • linetypess where there is a repeated pattern - e.g. wavy, indented (and most others)
  • linetypes in which there is some sort of central "feature", e.g. angled, nowy
  • linetypes which have a single "feature" extending the whole length, e.g. arched, double arched

Secondly, let use also note that any edge can end at one of three points

  • Exactly at the end point specified, e.g. arched, escartelly
  • Somewhere "outside" the end point specified, e.g. angled, bevilled
  • Somewhere "inside" the end point specified, e.g. angled opposite, bevilled opposite

This matters because of the "joins" to the next segment, especially if this join is visible on the shield itself. In particular think about the complications of this at the top and bottom joins on a chevron - we cannot naively just join the end of the previous edge to the specified end point and start again, we need to take account both of where the current line ends and where the next line should start.

(There are in fact even more complications, but we introduce these when we talk about flags later.)

Each variant edge type is defined by an encoded string, with each part separated by a ':', for example, angled is specified as follows:

0:100:i:o:h50v-{S}h50:O1

The meaning of each part is given below.

Linetype Category (required)

This is a single character with the following meanings:

  • 0 - the path section is placed once, at the centre of the edge
  • 1 - the path section will occupy the whole of the edge
  • * - the path section should be repeated as many time as will fit on the edge

Length of path section (required)

This is an integer value giving the end-to-end length of the path section

Line start position (required)

This is a single character with the following meanings:

  • - - the line starts at the normal position
  • i - the line starts inside the normal position
  • o - the line starts outside the normal position

Line end position (required)

This is a single character with the same meanings as above

Path section (required)

This is an arbitrary length section of an SVG path, it should be a valid fragment of an SVG path element "d" attribute and must use relative motions. Movement should be horizontally, from left to right, i.e. in the A vector direction. Most paths involve extensive use of the substution values described below.

Flags (optional)

This is a two character section with the following meanings (the '1' is redundant, I'll remove it soon):

  • U1 - This linetype should only appear on the "upper" edges of the shape (even if the shape spec suggests otherwise). This is mostly for embattled and friends which should only appear on the lower side of things if given explicitly.

  • R1 / O1 - How the linetype should appear on the "opposite" edge, see discussion below.

Substitution values

The whole of the linetype specification can make use of substitution values, these are denoted by braces, with the value to be substituted, optionally followed by an arithmetical operation. There are two possible substitution values:

  • S - The requested "size" of the edge features, basically the vertical height of the feature above and below the plain edge. This has a default value of 60 but can be overridden to fit on smaller objects like barrulets or cottices.

  • D - The total length of the edge (e.g. for the vector A1200, D has the value 1200)

The arithmetic operation can either '*' (multiply) or '/' (divide) and must be immediately followed by an integer or floating point value. So for example, the fragment of path:

v{S/2}

Would, with the default size value of 60 be replaced in the output by the string:

v30

Note that if you want a negative value of a substituted variable is easier to do -{S} than {S*-1} but both work.

Example Decoded

With this, we can now make sense of the example given above for the "Angled" edge:

0:100:i:o:h50v-{S}h50:O1

This edge is drawn once in the center (0:), it is 100 units long (100:), it starts inside the shape 'i:', ends outside the shape 'o' and consists of 3 path movements, right 50 units, up by the size value, right a further 50 units (hence the overall length of 100 units). Finally there is a flag which shows what should happen on the opposite edge.

A more complex Example

Let us look at the specification for the wavy linetype:

*:{S*3}:-:-:q{S*0.75},-{S} {S*1.5},0 q{S*0.75},{S} {S*1.5},0

This is telling us that:

  • *: The pattern should be repeated along the edge as many times as will fit
  • {S*3}: The length of the pattern is 3 times the specified size (180 units by default)
  • -: It starts in the normal postion (i.e. exactly on the specified edge)
  • -: It ends in the normal postion (i.e. exactly on the specified edge)
  • q{S*0.75... Is and SVG path element describing 2 quadratic bezier curves, all based on the specified size
  • There are no flags with this specification

The pattern here is a smooth curve above the edge, followed by a symmetrical, smooth curve below the edge, giving us the final version we see in the table above.

The "Opposite" Edge

One of the additional complexities is how each edge shape should be treated on the "opposite" side. The 'O' and 'R' flags control this, examples below TODO from here...

Angled Nowy
Angled Nowy
Dancetty Engrailed
Dancetty Engrailed

Excuses and Apologies

There are probably better ways of doing all of this. It is something that started out fairly simply 10 years ago and has had extra complexity bolted on to it as I found out more about heraldry and the quirks and tricks needed to replicate heraldic practice. Sorry about that.

Clone this wiki locally