Translating Blazon into Coats of Arms

University of Manchester
School of Computer Science
BSc (Hons) Computer Science with Industrial Experience
Final Year Project Report
Translating Blazon into Coats of Arms
Author:
Luke Torjussen
Supervisor:
Dr. Robert Stevens
May 2012
Abstract
Heraldry, the study of coats of arms, dates back to the 12th century and has been described as “the floral
border in the garden of history”. Blazon, the language of heraldry, allows us to describe unique designs
upon a coat of arms or shield. Heraldry is still used in the modern day in the form of coats of arms,
company logos, and banners.
This report describes how we can combine computer science techniques, including natural language
processing and computer generated imaging, to explore this ancient art. We see how BlazOnLion was
produced, to recognise sentences of Blazon and generate images of shields. We demonstrate the difficulties
of designing such a system, whilst justifying decisions made throughout the application’s development.
The final application was successful in recognising and generating images for a subset of Blazon. Some
rules of Blazon, including the rule of tincture, are too complex to represent in a grammar, so other steps
were taken to ensure the rules were followed. Due to the time constraints of the project, marshalling,
counter-changing, and charge placement were not handled by the application. If further work was to be
undertaken as described, the application has the potential to recognise a greater proportion of Blazon
and therefore successfully generate images for a wider range of coats of arms.
Translating Blazon into Coats of Arms
Author:
Luke Torjussen
Supervisor:
Dr. Robert Stevens
May 2012
Acknowledgements
Firstly I would like to thank my supervisor, Dr. Robert Stevens, for his enthusiasm and guidance which
has helped make this project a success.
Thanks to my parents and brother for providing so much support throughout my degree, especially
during my final year. I would also like to thank Ben Cope, Karl Sutt, Matthew Leach, Matthew While,
James Davey, and many others for testing and breaking the application and providing new ideas. Thanks
to Thomas Wozniakowski for proof reading this report.
Thanks to everyone I worked with at Goldman Sachs during my industrial placement for helping me to
become a better computer scientist.
Finally a big thank you to my friend Adam Jones for keeping me sane and providing moral support
throughout my university life.
Translating Blazon into Coats of Arms
Luke Torjussen
Contents
1 Introduction
1.1 Aim . . . . . . . .
1.2 Objectives . . . . .
1.3 Success criteria . .
1.4 Potential issues . .
1.5 Summary of report
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
1
2
2
2
2 Background
2.1 Heraldry . . . . . . . . . . . . . . . . . . . . . .
2.1.1 Origins of heraldry . . . . . . . . . . . .
2.1.2 Modern heraldry . . . . . . . . . . . . .
2.2 Blazon . . . . . . . . . . . . . . . . . . . . . . .
2.2.1 A complete sentence of Blazon . . . . .
2.2.2 Tinctures . . . . . . . . . . . . . . . . .
2.2.3 The field . . . . . . . . . . . . . . . . .
2.2.4 The charges . . . . . . . . . . . . . . . .
2.2.5 Lines of partition . . . . . . . . . . . . .
2.2.6 Counter-changing . . . . . . . . . . . . .
2.2.7 Charge positioning . . . . . . . . . . . .
2.2.8 Limitations of Blazon . . . . . . . . . .
2.2.9 Marshalling . . . . . . . . . . . . . . . .
2.3 Grammars . . . . . . . . . . . . . . . . . . . . .
2.3.1 What is a grammar? . . . . . . . . . . .
2.3.2 Example grammar . . . . . . . . . . . .
2.3.3 Recognising a sentence using a grammar
2.4 Existing applications . . . . . . . . . . . . . . .
2.5 Summary . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
3
4
5
5
5
6
6
7
8
8
8
8
9
9
9
10
10
11
3 Design
3.1 Requirements . . . . . . . . . . . . . . . . . . . . . . . . . .
3.1.1 Functional requirements . . . . . . . . . . . . . . . .
3.1.2 Non-functional requirements . . . . . . . . . . . . .
3.2 System architecture . . . . . . . . . . . . . . . . . . . . . .
3.2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . .
3.2.2 Service-oriented architecture . . . . . . . . . . . . .
3.2.3 Design patterns . . . . . . . . . . . . . . . . . . . . .
3.3 Application Flow . . . . . . . . . . . . . . . . . . . . . . . .
3.3.1 Recognising Blazon . . . . . . . . . . . . . . . . . . .
3.3.2 Creating an intermediate representation of the shield
3.3.3 Drawing the shield . . . . . . . . . . . . . . . . . . .
3.3.4 Handling the unlimited range of charges . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
12
12
12
13
14
14
14
15
16
16
18
19
21
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
i of vi
Translating Blazon into Coats of Arms
3.4
Luke Torjussen
3.3.5 User interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4 Implementation
4.1 Agile approach . . . . . . . . . . . . . . . . . . .
4.2 Technologies . . . . . . . . . . . . . . . . . . . . .
4.2.1 Programming platform . . . . . . . . . . .
4.2.2 Parser generator . . . . . . . . . . . . . .
4.2.3 Image format . . . . . . . . . . . . . . . .
4.2.4 Choices and justifications . . . . . . . . .
4.3 Interesting aspects of development . . . . . . . .
4.3.1 Drawing a varied field . . . . . . . . . . .
4.3.2 Specifying the correct number of tinctures
4.3.3 Following the rule of tincture . . . . . . .
4.3.4 Drawing multiple charges without overlap
4.3.5 Creating user friendly error messages . . .
4.3.6 Displaying a wait cursor . . . . . . . . . .
4.4 Summary . . . . . . . . . . . . . . . . . . . . . .
23
25
.
.
.
.
.
.
.
.
.
.
.
.
.
.
26
26
27
27
27
28
28
28
29
31
32
33
35
36
36
5 Results
5.1 Workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.2 An example workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5.3 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
38
38
38
41
6 Testing and Evaluation
6.1 Unit testing . . . . . . . . . . . . . . . . . . . .
6.1.1 Testing the grammar . . . . . . . . . . .
6.1.2 Testing the IR . . . . . . . . . . . . . .
6.1.3 Testing the drawing component . . . . .
6.1.4 Summary . . . . . . . . . . . . . . . . .
6.2 Success criteria . . . . . . . . . . . . . . . . . .
6.2.1 Plain field . . . . . . . . . . . . . . . . .
6.2.2 Divided field . . . . . . . . . . . . . . .
6.2.3 Single geometric charge . . . . . . . . .
6.2.4 Multiple geometric charges . . . . . . .
6.2.5 Single advanced charge . . . . . . . . .
6.2.6 Multiple advanced charges . . . . . . . .
6.2.7 Combination of geometric and advanced
6.2.8 Other objectives . . . . . . . . . . . . .
6.3 Evaluation . . . . . . . . . . . . . . . . . . . . .
6.4 Summary . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
42
42
43
43
43
43
43
43
44
46
48
49
51
52
52
52
52
7 Conclusion
7.1 Future work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.2 Personal development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7.3 Summary of report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
54
54
54
55
Bibliography
56
A Charge Layout
59
B Attitudes
61
C ANTLR Grammar
63
ii of vi
. .
. .
. .
. .
. .
. .
. .
. .
for
. .
. .
. .
. .
. .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
field division
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
charges
. . . . .
. . . . .
. . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Translating Blazon into Coats of Arms
Luke Torjussen
List of Figures
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
2.10
2.11
2.12
2.13
2.14
A labelled Heraldic Achievement . . . . . . . . . . . . . . . . . . . . . . . .
British Officers of Arms in Tabards . . . . . . . . . . . . . . . . . . . . . . .
International Code of Signals flags for the letters A, C, M, and H . . . . . .
“Argent, on a saltire gules five rustres argent, in chief a lion rampant of the
“Barry of ten, argent and gules” . . . . . . . . . . . . . . . . . . . . . . . .
“Azure, semé of fleur-de-lis” . . . . . . . . . . . . . . . . . . . . . . . . . .
“Sable, a cross Or” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
“Azure, three annulets Or” . . . . . . . . . . . . . . . . . . . . . . . . . . .
“Per fess embattled argent and gules” . . . . . . . . . . . . . . . . . . . . .
“Per fess wavy argent and gules” . . . . . . . . . . . . . . . . . . . . . . . .
How production rules are specified in BNF . . . . . . . . . . . . . . . . . . .
A simple grammar example . . . . . . . . . . . . . . . . . . . . . . . . . . .
Example sentence recognition . . . . . . . . . . . . . . . . . . . . . . . . . .
Example image generated by pyBlazon . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
4
4
5
6
6
7
7
8
8
9
9
10
11
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
3.10
3.11
3.12
3.13
3.14
Diagram of component interaction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A grammar to recognise Blazon for shield with a single colour field . . . . . . . . . . . . .
A refactored grammar to recognise Blazon for shield with a single tincture field . . . . . .
Ambiguous grammar recognising a shield with a divided field and a geometric charge . . .
Disambiguated grammar recognising a shield with a divided field and a geometric charge
An image showing issues with the rule of tincture and multiple charges . . . . . . . . . . .
A basic UML class diagram of a shield IR . . . . . . . . . . . . . . . . . . . . . . . . . . .
Shield outline composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Drawing being clipped to shield outline . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Evenly spaced charges being clipped by shield outline . . . . . . . . . . . . . . . . . . . .
Finding area for charges to avoid overlap with the shield outline . . . . . . . . . . . . . .
A grammar rule to match any word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A wireframe for the user interface of BlazOnLion . . . . . . . . . . . . . . . . . . . . . . .
A wireframe for an error message in BlazOnLion . . . . . . . . . . . . . . . . . . . . . . .
14
16
16
17
17
18
19
20
20
21
22
23
24
24
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
4.10
4.11
Diagram of how the rectangle can be split into rectangles . . . . . . .
Formulae for calculating co-ordinates of the triangles for “bendy” . .
Diagram showing how the shield outline hides some of the triangles . .
Equations for calculating the midpoint co-ordinates of a Bézier curve
Diagram showing correctly sized triangles for varying the field . . . . .
Code outlining the algorithm for drawing “bendy of 6” . . . . . . . .
Code to recognise number of tinctures for a field division . . . . . . .
Code to find the TinctureType of the field . . . . . . . . . . . . . . . .
Code to check whether the rule of tincture is being followed . . . . . .
Diagram showing hierarchy of charge drawing classes . . . . . . . . . .
Diagram showing rows and columns when drawing “6 roundels” . . . .
29
29
29
30
30
31
31
32
33
33
34
iii of vi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . . . .
. . . . .
. . . . .
second”
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Translating Blazon into Coats of Arms
Luke Torjussen
4.12
4.13
4.14
4.15
Diagrams showing how charge drawing area changes with presence of “chief ” and “base”
Diagram showing “gules 3 roundels argent a lion rampant or” with charges overlapping .
Code to use a wait cursor in GWT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
JSNI code for controlling the wait cursor . . . . . . . . . . . . . . . . . . . . . . . . . . . .
34
35
36
37
5.1
5.2
5.3
5.4
5.5
5.6
Screenshot
Screenshot
Screenshot
Screenshot
Screenshot
Screenshot
.
.
.
.
.
.
39
40
40
40
41
41
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
6.10
6.11
6.12
6.13
6.14
6.15
6.16
6.17
6.18
6.19
6.20
6.21
6.22
6.23
6.24
6.25
6.26
Expected image for “Gules” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Generated image for “Gules” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Expected image for “Erminois” . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Generated image for “Erminois” . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Expected image for “Per pale gules and argent” . . . . . . . . . . . . . . . . . . . .
Generated image for “Per pale gules and argent” . . . . . . . . . . . . . . . . . . .
Expected image for “Lozengy argent and gules” . . . . . . . . . . . . . . . . . . . .
Generated image for “Lozengy argent and gules” . . . . . . . . . . . . . . . . . . .
Expected image for “Sable semé of plates” . . . . . . . . . . . . . . . . . . . . . . .
Expected image for “Argent a saltire azure” . . . . . . . . . . . . . . . . . . . . . .
Generated image for “Argent a saltire azures” . . . . . . . . . . . . . . . . . . . .
Expected image for “Per pall sable gules and or a chevron reversed argent” . . . .
Generated image for “Per pall sable gules and or a chevron reversed argent” . . .
Expected image for “Or a roundel azure” . . . . . . . . . . . . . . . . . . . . . . .
Generated image for “Or a roundel azure” . . . . . . . . . . . . . . . . . . . . . .
Expected image for “Gules three bezants” . . . . . . . . . . . . . . . . . . . . . . .
Generated image for “Gules three roundels or” . . . . . . . . . . . . . . . . . . . .
Expected image for “Azure a chevron or with three stars the same” . . . . . . . . .
Generated image for “Azure a chevron or three stars or” . . . . . . . . . . . . . .
Expected image for “Azure a griffin rampant or langued and armed gules” . . . . .
Generated image for “Azure a griffin rampant or langued gules and armed gules” .
Expected image for “Or an anchor sable” . . . . . . . . . . . . . . . . . . . . . . .
Expected image for “Or a double-headed eagle displayed sable membered and beaked
Expected image for “Argent two lions combatant gules” . . . . . . . . . . . . . . .
Expected image for “Azure 6 lions rampant or langued gules” . . . . . . . . . . . .
Generated image for “Azure 6 lions rampant or langued gules” . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
gules”
. . . .
. . . .
. . . .
44
44
44
44
45
45
45
45
46
46
46
47
47
47
47
48
48
49
49
49
49
50
50
51
51
51
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
59
59
59
59
60
60
60
60
60
60
B.1 Attitude: “rampant” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
B.2 Attitude: “rampant guardant” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
B.3 Attitude: “rampant reguardant” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
61
61
61
A.1 “Or
A.2 “Or
A.3 “Or
A.4 “Or
A.5 “Or
A.6 “Or
A.7 “Or
A.8 “Or
A.9 “Or
A.10 “Or
a
a
2
2
3
3
4
4
4
4
of
of
of
of
of
of
BlazOnLion upon startup . . . . . . . . . . . . . . . .
wait cursor whilst processing the sentence “gules” . .
image generated for the sentence “gules” . . . . . . .
error message for a missing charge image . . . . . . . .
inputting data for new charge image . . . . . . . . . .
image generated for the sentence “gules a lion rampant
roundel gules” . . . . . .
roundel azure in chief ” .
roundels sable” . . . . . .
roundels gules in base” .
roundels vert” . . . . . .
roundels vert in pale” . .
roundels purpure” . . . .
roundels purpure 3 and 1”
roundels azure in bend” .
roundels purpure in fess”
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
iv of vi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
. . .
. . .
or”
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Translating Blazon into Coats of Arms
B.4
B.5
B.6
B.7
B.8
B.9
B.10
Attitude:
Attitude:
Attitude:
Attitude:
Attitude:
Attitude:
Attitude:
“statant”
“dormant”
“couchant”
“courant”
“salient”
“passant”
“sejant” .
. .
.
.
. .
. .
. .
. .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Luke Torjussen
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
v of vi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
61
62
62
62
62
62
62
Translating Blazon into Coats of Arms
Luke Torjussen
List of Tables
3.1
Table for storing charges and their image . . . . . . . . . . . . . . . . . . . . . . . . . . .
22
6.1
6.2
Table showing code coverage statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Table showing evaluation of BlazOnLion against sub-objectives . . . . . . . . . . . . . . .
42
53
vi of vi
Translating Blazon into Coats of Arms
Luke Torjussen
Chapter 1
Introduction
This chapter details the project’s aim and objectives, outlines how we can evaluate success, and highlights
some of the issues that could be faced.
1.1
Aim
In heraldry the coat of arms of a knight, family, or order can be described using a single sentence of the
Blazon language (see Section 2.2).
The project aim is to produce an application that automatically generates an image of a coat of arms
from a sentence of Blazon specified by the user. The application was named BlazOnLion.
1.2
Objectives
The project can be divided into the following parts: First we must write a grammar to check validity
of Blazon sentences. We then produce some Intermediate Representation (IR) for the described coat of
arms. Finally, given some IR the application should draw the represented shield.
These parts of the project dictate three objectives:
1. Write a formal grammar to recognise sentences of Blazon.
2. Represent a shield using some intermediate representation (IR).
3. Accurately draw a shield from a given IR.
We can measure the success of these objectives by checking which of the following sub-objectives are met.
Can the application represent shields. . .
A. . . . with a plain field? (see section 2.2.3).
B. . . . with a divided field? (see section 2.2.3).
C. . . . charged with a single geometric shape? (see section 2.2.4).
D. . . . charged with multiple geometric shapes? (see section 2.2.4).
E. . . . charged with a single image? (see section 2.2.4).
F. . . . charged with multiple images? (see section 2.2.4).
1 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
G. . . . charged with geometric shapes and images together? (see section 2.2.4).
H. . . . with counter-changed charges? (see section 2.2.6).
I. . . . the line of partition is varied? (see section 2.2.5).
J. . . . with charge positioning specified? (see section 2.2.7).
K. . . . that have been marshalled? (see section 2.2.9).
These sub-objectives allow us to easily divide the project into two to four week iterations, during which
we focus on achieving a sub-set of the functionality, i.e. one of the sub-objectives.
The application should provide warnings/errors to the user when. . .
1. . . . an invalid sentence of Blazon is provided.
2. . . . a sentence of Blazon disobeys the rule of tincture.
3. . . . the application has made some adjustments to the Blazon.
4. . . . the application fails to find an image for a specified charge.
1.3
Success criteria
Throughout the project we will create a corpus of Blazon sentences with an image of the corresponding
shield. Upon completion of the project, we will test using sentences from the corpus. The images
generated by the application can be compared with those in the corpus to see which objectives were met.
1.4
Potential issues
There are a number of areas in this project that may cause issues:
1. When writing the grammar, can we ensure that each division type rejects sentences of Blazon with
an incorrect number of tinctures?
2. When adding multiple charges onto a divided shield can we continue to ensure that the rule of
tincture is being followed?
3. When adding multiple charges onto a shield can we ensure they do not overlap?
4. How do we locate an image for an arbitrary charge added to the shield?
In later chapters of the report we will see how these issues can be resolved using careful design decisions
and implementation details.
1.5
Summary of report
This chapter introduced the topics covered by this project. The rest of this paper describes the approach
followed to build an application to meet the aims and objectives. Section 2 provides information into
the background of heraldry, Blazon, and the use of grammars. Section 3 discusses the different options
considered during the design of the application. Section 4 describes the approach taken to implement the
application. Section 5 describes the applications workflow. Section 6 studies the testing and evaluates the
applications performance against the objectives. Section 7 concludes the report, outlining the project’s
success, skills learnt, and a possible approach for future work.
2 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Chapter 2
Background
This chapter provides background knowledge for the topics discussed in the report. We discuss the
origins of heraldry, details of the Blazon language, and how to construct sentences. We see how sentences
are recognised using a grammar. Finally we analyse existing applications, identifying their strengths,
weaknesses, and how we can learn from them.
2.1
2.1.1
Heraldry
Origins of heraldry
Heraldry is the study of coats of arms. A coat of arms is a coloured emblem used to identify an individual,
family, or community. Knights would carry a patterned shield into battle, as the customary helmet made
them otherwise unidentifiable. This was resolved by drawing a pattern onto their shield [1]. The phrase
coat of arms arose in the 12th–13th century when knights began to display this pattern on a fur coat
worn over chain mail [2].
Figure 2.1: A labelled Heraldic Achievement [3]
3 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Coat of arms is synonymous to shield, although often incorrectly used to refer to the whole heraldic
achievement [2] which is made up of the shield, crest, motto, and supporters (see figure 2.1). This paper
focuses on the coat of arms, ignoring the rest of the achievement. Throughout the paper we refer to a
coat of arms as a shield.
2.1.2
Modern heraldry
Heraldry is still used today with arms being granted to individuals, companies, and institutions. At
ceremonies of the British State such as Royal Weddings or Jubilees we see officers of arms wearing their
Tabards (see figure 2.2). Officers of arms are members of the royal household appointed to manage
heraldic records, including approval of new shields [3].
Figure 2.2: British Officers of Arms in Tabards [3]
Although most people no longer carry shields to make them identifiable, companies use logos to make
their products recognisable. The design of some logos has been influenced by heraldry [1]. For example,
the logos of car manufacturers Peugeot, shows a “lion rampant”, and Alfa Romeo, shows a marshalled
shield with a cross and a crowned serpent.
Figure 2.3: International Code of Signals flags for the letters A, C, M, and H [4]
Heraldry has also influenced systems for signs. The International Code of Signals (ICS) use flags to
represent letters of the alphabet and digits (see figure 2.3). The flags use heraldic tinctures, have divided
fields, and many use large geometric shapes, designed to be seen from a distance.
4 of 73
Translating Blazon into Coats of Arms
2.2
Luke Torjussen
Blazon
2.2.1
A complete sentence of Blazon
Blazon is the language used to formally describe the pattern on a shield. When describing a shield we
first describe the field, or background, then describe each charge [3]. Figure 2.4 shows a labelled shield
for the sentence “Argent, on a saltire gules five rustres argent, in chief a lion rampant of the second”.
Figure 2.4: “Argent, on a saltire gules five rustres argent, in chief a lion rampant of the second” [5]
1. “Argent”, states that the background of the shield is silver/white.
2. “on a saltire gules”, tells us that there is a red “saltire” 1 . The word “on” informs us that some
other charge(s) will be placed upon the “saltire”.
3. “five rustres argent”, means we will place 5 silver/white “rustres” 2 on the “saltire”.
4. “in chief ”, tells us to place the next charge in the upper portion of the shield.
5. “a lion rampant”, states that we will place a rampant3 lion.
6. “of the second”, states the lion uses the second tincture in the sentence, i.e. “gules”.
We now detail how each part of a sentence is described.
2.2.2
Tinctures
In Heraldry we describe the field and charges with tinctures. The tinctures are divided into the colours
— “Azure” (blue), “Gules” (red), “Purpure” (purple), “Sable” (black), and “Vert” (green) — and the
metals — “Or” (gold/yellow) and “Argent” (silver/white).
1A
saltire is a diagonal cross.
2A
rustre is a lozenge shape voided by a circle in the centre.
3 Rampant
means it is viewed in profile, standing on its hind legs, with its foreclaws raised.
5 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
When placing charges onto a field tinctured using a metal, they must be tinctured using a colour and
vice versa. This is known as the rule of tincture. This rule is used because on the battlefield there should
be sufficient contrast between tinctures to distinguish them.
There is a third group of tinctures known as the furs [1]. These are patterns repeated across the field or
charge and are either in the shape of squirrel skin (“Vair”) or the winter coat of a stoat (“Ermine”) [3].
Furs are exempt from the rule of tincture.
2.2.3
The field
The field can either be a single tincture, or divided using geometrical shapes with multiple tinctures.
Each division type has a number of tinctures associated with it. If an incorrect number of tinctures is
specified, the sentence of Blazon is invalid. For example, “per pale gules or and sable”, states we are
dividing the field in two using a vertical line, but we have incorrectly provided three tinctures. When we
divide the field the tinctures are placed side by side, so do not need to follow the rule of tincture.
The field may also be varied ; this is where we divide the field using a repeated pattern, usually the shape
of an ordinary(see section 2.2.4). For example, “paly” means the field has vertical stripes. When we vary
the field we can specify the number of sections we want, e.g. “paly of 6” or “barry of 10” as in figure 2.5.
Another variation of the field is described as semé. A field can be depicted as semé by drawing a charge
many times across it. We first describe the tincture of the field followed by the charge to be repeated,
with its tincture. Figure 2.6 shows a field “semé of fleur-de-lis or”.
Figure 2.5: “Barry of ten, argent and gules” [6]
2.2.4
Figure 2.6: “Azure, semé of fleur-de-lis or” [6]
The charges
Once we have described the field, we name each of the charges to be added. A charge can be a simple
geometric shape or a more complex charge such as a beast, bird, or plant. When describing a geometric
charge we state its name and tincture. Geometric charges that span the width or height of the shield
are known as ordinaries (an example can be seen in figure 2.7). Other geometric charges are known as
mobile charges.
A mobile charge’s position on the shield can be changed and we can have multiples of them. Common
mobile charges include “annulets”, “roundels”, and “lozenges”. When building a shield a single charge
will be placed in the centre of the field. As we introduce more charges they reduce in size and are
6 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 2.7: “Sable, a cross Or” [7]
Figure 2.8: “Azure, three annulets Or” [7]
repositioned to avoid overlap (see appendix A). An example of multiple geometric charges can be seen in
figure 2.8.
When describing birds, beasts, and other charges, which we will now refer to as advanced charges, we specify their name, tincture, and pose, known as an attitude. Appendix B shows images for some commonly
used attitudes.
In the middle ages advanced charges included lions, fleur-de-lis, and stars. The range of charges has
increased over time and is now considered unlimited [1]. Any beast, bird, plant, tool, inanimate object,
or geometric shape can be considered a charge. Modern coats of arms show a person’s or institution’s
interests or research areas. An example of this is the shield of the University of Warwick which depicts
atoms and a double helix of DNA [8].
We may tincture an advanced charge in the usual way or state they are tinctured “proper”. A charge
tinctured “proper” is depicted in its real-world colours [3]. We may also tincture body parts of a charge
differently to the main body of the charge. For example, a lion may be “langued azure” meaning it has
blue tongue, “armed argent” meaning its claws are white/silver, or “pizzled gules” meaning it has a red
penis.
2.2.5
Lines of partition
Dividing lines of the field or around a charge are straight unless otherwise stated. Lines can be varied
using a number of patterns including “indented” (zig-zagged), “wavy”, and “embattled” (a square wave,
representing battlements of a castle) [3].
To vary the line of a divided field we write type of division, followed by the variation of line to use, and
finally we state the tinctures in the usual way, e.g. “Per fess wavy sable and or”. We may also use these
lines when describing ordinaries in the same way. For example, “a bend indented or” states we have a
“bend” tinctured “or”, with a zig-zagged line used for its edges.
7 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 2.9: “Per fess embattled argent and gules” [6]
2.2.6
Figure 2.10: “Per fess wavy argent and gules” [6]
Counter-changing
When a charge is placed over a line of partition, rather than stating its tincture, we can say it is “counterchanged”. For example, we could divide a field “per pale or and gules”. This means the left side of the
field is tinctured “or” and the right side is tinctured “gules”. A “counter-changed” charge placed onto
this field will have its left side tinctured “gules” and its right side “or”.
2.2.7
Charge positioning
We may state where a charge is situated on the shield. For example, “in chief ” places the charge in the
upper section of the shield. When there are multiple charges we can state the formation in which they
appear. For example, “three roundels or 1 and 2” tells us to put one roundel at the top, with two below
it. We may also state a shape in which multiple charges appear. For example, a “bend” is a diagonal
line from the top left to the bottom right corner. Charges arranged “in a bend” lie along an imaginary
diagonal line from the top left corner to the bottom right corner.
2.2.8
Limitations of Blazon
There are some details that Blazon is unable to describe. The shape of shields varies, with certain shapes
being prominent in different countries and centuries of origin [2]. Blazon lacks a way to specify the shape
of a shield, leaving this decision to the artist. Tinctures in heraldry represent a colour or metal but the
shade used on the shield is a question of artistic licence. For example, we could depict a shield tinctured
“azure” with royal, sky, or even navy blue. We can depict each charge in a number of different ways, all
of which are correct. A charge is only drawn incorrectly if the image no longer resembles that charge.
2.2.9
Marshalling
Marshalling is the process by which we combine multiple shields. A number of methods may be used for
marshalling, including impalement, where the field is divided “per pale” with one of the coats of arms
displayed in each half. We may also use quartering, by which we display a coat of arms in each quarter
of the new coat.
8 of 73
Translating Blazon into Coats of Arms
2.3
Luke Torjussen
Grammars
In order to recognise sentences of a language we must have some formal representation of the language’s
syntax. To understand a sentence of Blazon we must first check whether it conforms the syntax of the
language.
2.3.1
What is a grammar?
A formal grammar is a method of describing the syntax of a language. Languages can be represented
using terminal symbols, non-terminal symbols, and production rules [9]. Languages that have a finite
number of symbols4 are described as formal languages.
Terminal symbols in a grammar are the letters/words we use in sentences e.g.“gules”, “lion”. Nonterminal symbols do not appear in sentences of the language, but are used in the production rules. The
production rules show how we can build sentences using the symbols.
Backus-Naur Form (BNF) is a common notation for expressing a grammar. BNF production rules allow
us to replace non-terminal symbols on the left hand side of a production rule, with symbols from the
right hand side [10]. Although BNF allows alternatives to be specified using the vertical bar it has
been extended to simplify the description of more complex languages. Extended BNF (EBNF) adds
operators to allow optional symbols or allow a symbol to be specified a number of times without the use
of recursion [10]. Production rules in BNF are specified in the form shown in figure 2.11.
symbol ::= alternative1 | alternative2 | . . .
Figure 2.11: How production rules are specified in BNF
2.3.2
Example grammar
Figure 2.12 shows a grammar for recognising mathematical equations. The grammar has non-terminal
symbols S and B. S is a special non-terminal symbol known as the starting symbol. The terminal symbols
are the digits 0 to 9, (, ), +, −, /, and ×.
S ::= B | (S) | S + S | S − S | S × S | S / S
B ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Figure 2.12: A simple grammar example [11]
We can take the sentence 5 + (3 × 7) and check whether it can be recognised using the grammar (follow
figure 2.13). We start with symbol S and use the third part of the production rule to replace it with
S + S. The first part of the production rule allows us to replace S with B. We replace B with terminal
symbol 5. There remains a non-terminal symbol S which is replaced with (S) using the second part of
the production rule. We take S and replace it with S × S via part five of the rule. The remaining
non-terminal S symbols can in turn be replaced with the non-terminal symbol B and then the digits 3
and 7 accordingly.
4 In
the case of natural language, a symbol can be used to represent a word.
9 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
S ⇒ S + S
⇒ B + S
⇒ 5 + S
⇒ 5 + (S)
⇒ 5 + (S × S)
⇒ 5 + (B × S)
⇒ 5 + (3 × S)
⇒ 5 + (3 × B)
⇒ 5 + (3 × 7)
Figure 2.13: Example sentence recognition
2.3.3
Recognising a sentence using a grammar
Given a grammar for a language we can construct a recogniser for sentences. A recogniser is made up
of a Lexer, which reads characters and produces a sequence of tokens 5 , and a Parser, which checks that
the sequence of tokens match the syntax of a valid sentence. Given the snippet of Blazon “lion rampant
gules”, a Lexer could produce the tokens “BEAST ATTITUDE TINCTURE”. The Parser then checks
whether a sequence of tokens is valid.
2.4
Existing applications
There are a number of free applications available on the World Wide Web (refered to as ‘the web’) that
draw shields using a wizard style interface. One example is The Medieval Shield Designer [12]. This
application is under construction and has a limited range of charges that can be added.
The only application found that provides automatic drawing of shields from a Blazon sentence is pyBlazon [13]. This application parses a sentence of Blazon using PLY 6 and generates a Scalable Vector
Graphics (SVG) image representing the described shield. When specifying a charge in Blazon we must
gives its name, attitude, and tincture. pyBlazon sacrifices this formality to avoid the issue of the unlimited
range of charges. When entering a sentence of Blazon a user can specify a URL to an image for a charge
as in figure 2.14.
There is a lack of applications that automatically draw shields from a sentence of Blazon. Although
some wizard based applications provide a sentence of Blazon for the constructed shield, the drawing itself
requires user interaction. To account for drawing the unlimited range of charges, the applications that
automate drawing sacrifice the formality of representing charges in Blazon. BlazOnLion will be designed
to follow all rules of Blazon and handle the unlimited range of charges.
5A
token is a sequence of characters recognised by a symbol.
6A
port of Lex and Yacc for the Python programming language.
10 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 2.14: “Per pale argent and vert 3 <http://us.i1.yimg.com/us.yimg.com/i/ww/beta/y3.gif>
proper” [13]
2.5
Summary
In this chapter we discussed origins of heraldry, the structure of sentences in Blazon, what a grammar
is, how we represent them, and how they are used to recognise sentences. Finally we outlined existing
applications and how we can learn from the approach they use.
11 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Chapter 3
Design
This chapter outlines the project’s functional and non-functional requirements. We detail how the application architecture allows us to meet those requirements and how each component of BlazOnLion was
designed to accomplish the objectives set out in section 1.2.
3.1
3.1.1
Requirements
Functional requirements
Recognising Blazon
Using the sub-objectives set in section 1.2 we can prioritise the parts of Blazon to be recognised by the
grammar, by deciding what we must recognise, should recognise, and would like to recognise.
The grammar must recognise plain and divided fields, sub-objectives A and B, as these are the simplest
sentences of Blazon. We must also recognise sentences with a single geometric charge or image (subobjectives C and E).
BlazOnLion should also recognise sentences with multiple geometric charges or multiple images (subobjectives D and F). This means we can recognise a sentence specifying multiple occurrences of a particular
charge. We should also allow recognition and drawing of varied lines of partition (sub-objective I).
The remaining sub-objectives — G, H, J, and K — are parts of Blazon we would like BlazOnLion to
recognise. Recognising sentences with multiple types of charge specified is not essential but would allow
us to deal with a greater number of Blazon sentences. Counter-changing and the positioning of charges
are the lowest priority.
Shield drawing
BlazOnLion will allow a user to enter a sentence of Blazon and generate an image of the described shield.
Section 3.2 describes how the application’s components interact in order to meet this requirement. Once
the image has been generated it must be displayed on the user interface.
12 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Image referencing
The range of charges in Blazon is unlimited so BlazOnLion must import images to add to the generated
shield. This could be handled in number of ways: we could use the same approach as pyBlazon, see
section 2.4, but this ignores the correct way of specifying charges in Blazon. Alternatively the application
could use a database to store images. When a user entered a sentence containing a charge, the application
could retrieve an image using the charge name, attitude, and tincture.
3.1.2
Non-functional requirements
Usability
The user interface should conform to usability principles defined by Dix et al. [14]. The interface should
be familiar to users: a user should open BlazOnLion and be able to interact with it in a familiar way. The
interface should be learnable: each time somebody uses BlazOnLion their productivity should improve.
All parts of the interface should be consistent: they should use the same colour scheme, fonts, and
interaction style.
Performance
The application must remain responsive at all times. Complex computation on the client can block other
processing taking place. By moving complex computation from the client to a server using asynchronous
remote procedure calls, we allow processing to be done without interrupting the user interface. If a task
is long running, a user should be made aware by displaying a wait cursor e.g. Microsoft’s hourglass.
Portability
We must ensure that functionality and visual components of BlazOnLion are consistent across multiple
platforms. We should follow the principle of platform independence described in the slogan for Java,
“Write once, run anywhere” [15]. During the project’s deployment phase, all source code should remain
the same with a single version of BlazOnLion deployed to run on all platforms.
Adaptability
The components of BlazOnLion should be well separated and provide adaptability. This separation
would mean BlazOnLion could have alternative implementations of each component, for example drawing
different types of image (JPEG, SVG, PNG). It would also allow some components to be used by other
applications. For example, somebody could write a different parser whilst utilising the already developed
IR and drawing components.
Error handling
BlazOnLion must handle and report errors. If an error occurs, whislt parsing a sentence for example,
the user will be notified of the problem. The error messages displayed must be concise, detailed, and use
language appropriate to the user.
13 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Testability
In order to assert correct behaviour of the application it must be testable. Incorporating testing as part
of the development process ensures that code is testable. Well structured code facilitates unit testing
which can be automated; “Test Early. Test Often. Test Automatically” [16]. Other more complex testing
must be done manually, but unit testing provides the knowledge that individual components behave as
expected.
3.2
3.2.1
System architecture
Overview
In section 1.2, we outlined three main components of BlazOnLion:
ˆ A grammar for recognising Blazon,
ˆ an Intermediate Representation for Shields,
ˆ and a mechanism for drawing an image from a shield representation
We also need an interface component so users can interact with the application. The interaction of
components can be seen in figure 3.1.
Figure 3.1: Diagram of component interaction
3.2.2
Service-oriented architecture
Service-Oriented Architecture (SOA) can be used to separate concerns in a software system, enforces loose
coupling of components, and provides a level of abstraction. The service may carry out some intensive
computation or manage data that the client should not be concerned with. Services may be hosted
remotely server, with many clients connected to it.
Usually when we use a method in an object-oriented programming language we calling a method on
an object on the local host. When calling a method on a service it becomes a remote procedure call
(RPC). RPCs behave in the same way as standard method calls, but the object used is hosted remotely.
14 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
When using RPC, messages are passed via a network and then a response is sent back by the service.
If the network is slow or computation is particularly expensive, the client is blocked until the service
responds, which can render the client unusable. To solve this issue we can make the RPCs asynchronous.
An asynchronous RPC lets us register a callback method to process the response of the service when it
completes.
The asynchronous RPCs can increase performance as the client can carry out other tasks whilst the service
is busy. Then when the service completes, it notifies the client which will call the callback to handle the
RPCs response. By separating functionality in this way, we improve the testability of each component.
If components are closely coupled it may be difficult to test them individually. The abstraction provided
by SOA also gives us the opportunity to swap in alternative components. The service can also be made
available to other clients.
3.2.3
Design patterns
Each component has of a number classes with assigned responsibilities. Design patterns are practical
solutions used to solve object-oriented design problems [17]. Design patterns used to aid the design of
BlazOnLion are detailed below.
Factory
Creation logic for some objects may be complicated. The Factory pattern allows us to move the creation
logic to another class, helping us restrict each class to a single responsibility. This principle is known as
high cohesion [18]. This pattern is used for creating objects to draw parts of the shield.
Interpreter
An interpreter specifies how a language is recognised using a grammar. This the pattern allows us to
parse sentences of Blazon using the grammar we create [17].
Null Object
The null object pattern defines a class implementation with neutral behaviour [19]. This can be used for
representing an invalid shield. For example, when an invalid sentence of Blazon is entered, we return a
null shield. When we query its state in order to draw it, what charges it has etc., it returns null.
Observer
Since we are using asynchronous method calls, we need some way to be notified when the method
completes. The observer patter allows us to subscribe to some observable object [17]. When the observed
object’s state changes, it notifies the observing objects. This pattern can also be used to observe state
changes in the user interface. For example, when a user clicks a button on the interface, the button object
sends a message to an observer carrying out the associated action.
Strategy
The strategy pattern allows us to define a set of related algorithms using inheritance. The strategies share
a common interface, allowing us to select which strategy should be used at runtime [17]. For example,
15 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
the drawing of each charge can be considered a collection of strategies which are selected according to
which charges are to be drawn.
Template Method
The template method defines the skeleton of an algorithm without implementation details [17]. This
can be used to outline the algorithm for drawing a shield. We can refer to the interface of the strategy
pattern within the template method to select how to draw a charge at runtime without changing the
overall algorithm.
3.3
Application Flow
In the following sections we will detail the flow of data followed to convert a sentence of Blazon into an
image.
As outlined in section 3.2, BlazOnLion is made up of four main components. Firstly we have a grammar
to recognise sentences of Blazon. From the grammar we will produce a parser which will create an
Intermediate Representation as it parses sentences of Blazon. We shall see in the following section that
not all validation of Blazon sentences is possible during the first pass of the parser. Some validation must
carried out by querying the IR of the shield that we create. Once we have created the IR we annotate
it to tell the drawing component how to import images for advanced charges. Finally, we can pass the
IR to the drawing component and generate the shield image. Details of each stage are presented in the
following sections.
3.3.1
Recognising Blazon
To satisfy objective 1, we must write a grammar to recognise sentences of Blazon; this is known as
the Interpreter pattern [17]. When writing the grammar, we should use the sub-objectives specified in
section 1.2, to decide what to include at each iteration of development.
Starting with sub-objective A, the grammar should match sentences that describe a shield with a plain
field. Figure 3.2 shows an example of how this grammar may look.
shield ::= “argent” | “azure” | “gules” | . . . | “vert”
Figure 3.2: A grammar to recognise Blazon for shield with a single colour field
As we complete each of the sub-objectives the grammar will become more complex and each rule may
require refactoring. We can refactor the grammar from figure 3.2 and create a tincture symbol which
recognises each tincture (see figure 3.3). This symbol can be re-used throughout the grammar and stops
us repeating the list of tinctures in each production rule.
shield ::= tincture
tincture ::= “argent” | “azure” | “gules” | . . . | “vert”
Figure 3.3: A refactored grammar to recognise Blazon for shield with a single tincture field
16 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 3.4 shows how the grammar may look if it handled sentences described by sub-objectives A to C.
Here we can see ambiguity has already been introduced in the grammar. The words that define an
ordinary such as “bend” and “cross” can be used as either a charge or as a method to divide the field.
The meaning of these words is determined by context. These words would match multiple symbols
meaning the parser would be unable to decide which one to use. We need to remove ambiguity from this
grammar as much as possible.
shield ::= field charge∗
field ::= tincture | per div tincture+
charge ::= determiner charge name tincture
tincture ::= “argent” | “azure” | “gules” | . . . | “vert”
div ::= “bend” | “cross” | “chequy” | . . . | “lozengy” | “saltire”
charge name ::= “annulet” | “bend” | “cross” | . . . | “roundel” | “saltire”
determiner ::= “a” | “an”
per ::= “per”
Figure 3.4: Ambiguous grammar recognising a shield with a divided field and a geometric charge
Disambiguating the grammar gives us a grammar similar to the one shown in figure 3.5. Now “cross”
etc. have been moved to a new symbol called charge or div name. Now when we find the word “cross”
we know that it can only be one type of symbol (charge or div name). Words recognised by this new
token can be used in both contexts described above, as both the field and charge production rules accept
the token.
shield ::= field charge∗
field ::= tincture | per (div | charge or div name) tincture+
charge ::= determiner (charge name | charge or div name) tincture
tincture ::= “argent” | “azure” | “gules” | . . . | “vert”
div ::= “chequy” | . . . | “lozengy”
charge or div name ::= “bend” | “cross” | . . . | “saltire”
charge name ::= “annulet” | . . . | “roundel”
determiner ::= “a” | “an”
per ::= “per”
Figure 3.5: Disambiguated grammar recognising a shield with a divided field and a geometric charge
Handling potential issues
In section 1.4 we outlined some potential issues. We will now address issues 1 and 2.
Issue 1: When writing the grammar, can we ensure that each division type rejects sentences
of Blazon with an incorrect number of tinctures? As mentioned in Section 2.2.3, the field can
be either a single tincture, or divided into a number of sections. We could split the division types
into groups according to the number of tinctures that must be used with them, giving us symbols like
17 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
div with 2 tinctures. Unfortunately, some division types like “per cross” can have two or four tinctures,
meaning we would need other symbols such as div with 2 or 4 tinctures, severely bloating the grammar
and making it difficult to understand.
Another problem raised is, when varying the field we can specify a number of times [3] for the shape to
be repeated. For example we can have “paly of 6”, which gives us six vertical stripes, but we could use
“paly of 8” or any other even number. In the case of “paly of 6”, the number of tinctures could be two or
three, but for “paly of 8” we would need either two or four tinctures. The number of tinctures required is
discovered as we parse. This means we are unable to check the number of tinctures is correct in a single
pass.
An alternative solution to the issue would be to use the EBNF syntax to recognise a token at least
once. Whilst creating the IR of the shield we can check whether the number of tinctures specified was
as expected. For example, if we store the IR as software objects, each division type could be a different
class with an expected number of tinctures.
Issue 2: When adding multiple charges onto a divided shield can we continue to ensure that
the rule of tincture is being followed? If the field is tinctured using a colour then the charge must
be a metal (see section 2.2.2). This simple situation can be represented in the grammar. If we divide the
field “per fess” and tincture both halves a colour, any charges placed onto the field must be a metal (or
a fur, or “proper”). If we tincture one half as a colour and the other as a metal, charges placed onto the
field can be of any tincture. When we add two charges, they are no longer along the dividing line of the
field. Can use the grammar to ensure the rule of tincture is followed in this case?
Figure 3.6: An image showing issues with the rule of tincture and multiple charges
Figure 3.6 shows three examples of a field “per pale or and gules” with one, two, and three “roundels
azure”. In the left-most image we see the single “roundel” overlapping the line of partition. This means
it does not need to obey the rule of tincture. When we add a second “roundel”, neither of them overlap
the division line (as shown in the middle image). The “roundel” labelled 2 is a colour placed on a colour,
disobeying the rule of tincture. The right-most image shows a similar situation.
The way the field is tinctured and divided changes the tinctures that charges may use. If a position has
been specified for a charge, the grammar will need to look ahead to check whether the rule of tincture has
been followed. Trying to solve this issue through the grammar will be complex. An alternative solution
is to check the type of tincture, colour or metal, during construction of the shield IR. This enables us to
ask the field what type of tinctures can be placed at a certain position.
3.3.2
Creating an intermediate representation of the shield
To satisfy Objective 2, we must design some Intermediate Representation for the shield.
18 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
As highlighted in the previous section, checking validity of sentences may not be possible in a single pass.
It would be useful, for the IR of the shield to have its own constraints. For this reason it seems the
appropriate form for the IR should be collection of software objects. We instantiate a class by calling its
constructor. We may, for example, have a DividedField class which needs a name and a list of tinctures for
construction. During instantiation we can check whether the number of tinctures is correct and react in
an appropriate manner. Once a sentence has been parsed, we can create the intermediate representation
and carry out checks on more complex rules such as the rule of tincture.
Representing the shield
Before designing an object-oriented system we must carry out object-oriented analysis (OOA). During
OOA we identify objects in the domain to be represented in software.
From the domain of Blazon we can identify the following classes — Shield, Field, Type of Division,
Tincture, and Charge. From section 2.2 we know there are multiple types of tincture and charge. This
type of relationship can be represented in software using inheritance. Figure 3.7 shows a UML class
diagram of how we may represent the shield in software.
Figure 3.7: A basic UML class diagram of a shield IR
3.3.3
Drawing the shield
To satisfy Objective 3, we must create a component for drawing a shield from some given IR.
The drawing of the shield can be separated into many tasks. We can create software objects, each with the
responsibility of drawing a particular part of the shield. For example we may have DividedFieldDrawer,
RoundelDrawer, and SaltireDrawer classes. Each drawer is responsible for drawing a part of the shield.
Given two dimensional co-ordinates the drawer should draw the correct shape of the correct size and
tincture. Separating drawing into classes in this way follows the single responsibility principle. This
principle states that every object should have a single responsibility which should be encapsulated from
other objects [20].
19 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
We can use the Strategy and Template Method design patterns to define the drawing algorithm. The
template method defines the structure of the algorithm, i.e. first we draw the field, then we draw each
charge. Each drawer defines the behaviour or strategy to be used for drawing the shield. This combination
allows us to easily alter the way we draw, by selecting a different drawer class, without changing the
structure of the algorithm [17].
Deciding which type of drawer to create may be complex. We need some other class to create a drawer
appropriate to the IR. For example, if the shield contains a “cross”, we want to create a CrossDrawer.
This approach to object creation is known as the Factory pattern [18].
Figure 3.8: Shield outline composition1
The shield’s outline should be drawn from three straight lines and two arcs, as shown in figure 3.8. When
adding a field and charges we must ensure nothing overlaps the shield’s outline. Calculations involving
the arcs of the shield outline may be complex. We need to represent the shield drawing area in a simpler
way. We could represent the shield as a rectangle, and clip all drawing to the shape of the shield. This
would simplify calculations for field division and the positioning of charges. Once the shield has been
drawn we can clip the image using the outline of the shield, as shown in figure 3.9.
Figure 3.9: Drawing being clipped to shield outline2
One issue with this, as shown in figure 3.9, is the upper portion of the field appears larger than the
lower portion. When we split the rectangle in half the portions are the same until we clip to the shield
outline. Upon clipping we reduce the visible area of the lower portion. This may cause shields to look
disproportionate, but as it will reduce complexity of calculations we will ignore it.
1 Image
drawn manually.
2 Image
generated by BlazOnLion and amended manually.
20 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
To draw the geometric charges, we can specify the co-ordinates of each point of the shape. Most geometric
charges can be constructed from a small number of points. For these charges, we can tell BlazOnLion
where to place points to draw the charge. To draw an advanced charge such as a lion, BlazOnLion
would need to know where to place hundreds of points. We have already mentioned the unlimited range
of charges; specifying points for how to draw each of the commonly appearing charges in a number of
attitudes would take a very long time. To get BlazOnLion to draw all possible charges we must find a
way to import charges from a new source.
Handling potential issues
In section 1.4 we outlined some potential issues. This section will address issue 3.
Issue 3: When adding multiple charges to a shield can we ensure the images do not overlap?
When there is a single charge on the shield it will be placed in the centre. As we increase the number of
charges their positions change, as shown in appendix A. The charges should also decrease in size to stop
them overlapping with each other, and with the shield outline. Given X occurrences of a charge, we can
divide their original size by X to find a new size, to stop them overlapping with each other.
Figure 3.10: Evenly spaced charges being clipped by shield outline3
We must also find points on the shield at which charges will not overlap the edges of the shield. For
example if we place 4 “roundels” at evenly spaced points on the shield, as shown in figure 3.10, when we
clip the image to the shield outline we see the lower two “roundels” display incorrectly.
To avoid this issue, we draw an imaginary line that dictates the area in which a charge can be drawn.
First we draw the top of charges. Next we draw a line from the outer edge of the widest charge, to
the shield outline vertically below. We can then draw a line horizontally to the other side of the shield
outline, followed by another vertical line to complete the rectangle (see figure 3.11). Once we have found
the area, we can adjust the row positions of the charges to give even spacing within the charge area.
3.3.4
Handling the unlimited range of charges
In section 2.2.4 we mentioned the unlimited range of charges. It was also described as a potential issue
in section 1.4.
3 Image
generated by BlazOnLion and amended manually.
4 Image
generated by BlazOnLion and amended manually.
21 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 3.11: Finding area for charges to avoid overlap with the shield outline4
The previous section discussed how we could create a drawer class for each charge we wanted to draw.
Creating a drawer for every charge, given an unlimited range, would be impractical. Instead we must find
a way to import charge images from another source. We must also find a way to deal with the unlimited
range of charges within the grammar.
In section 2.4 we that saw pyBlazon allows users to reference URLs directly in a sentence of Blazon. The
issue with this is it sacrifices the formalities of specifying charges in Blazon with an attitude and tincture.
In BlazOnLion we will allow users to import images from URLs whilst following the rules of Blazon.
Charge database
When BlazOnLion finds an advanced charge such as a “lion” in the shield IR, it will search a database
for an image to place on the shield. The database only needs one table to store information about the
charge and where the image is located. Table 3.1 shows a description for the attributes in the table.
There should only be one image for each combination of attributes. We can either create a primary key
by concatenating the other fields together, or using them as a composite key.
Attribute Name
Type
Description
ID
string
A unique identifier for a charge.
Charge
string
The type of charge. e.g. “lion”
Attitude
string
The attitude of the charge. e.g. “rampant”
Attitude Modifier
string
A modifier of the charge’s attitude. e.g. “reguardant”
Tincture
string
The tincture of the charge. e.g. “gules”
Body Parts
string
The body parts specified of a different tincture. e.g. “langued azure”
Image Source
string
The URL at which the image for the charge is located.
Table 3.1: Table for storing charges and their image
Users have the option to add new images to this database. This will allow BlazOnLion to find an image
for any charge specified. A user may abuse this ability as it difficult to validate the data. There are a
number of ways a user could misuse it:
1. Adding a charge with the wrong type of attitude. e.g. A “lion” with a flying attitude.
22 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
2. Adding a charge with an incorrect image. e.g. Describe a “lion” but give an image of a “honey
badger”.
3. Adding nonsensical data. e.g. “A foo blah”.
Unless we add an approval system, it will be very difficult to validate the adding of charges. For now we
must trust the users of BlazOnLion.
Grammar
The grammar contains non-terminal symbols that are resolved to words in Blazon. For a charge to be
recognised it must appear in the grammar.
When describing a charge in Blazon we must specify its attitude. Only certain attitudes can be applied
to each charge. There are attitudes such as “rampant” and “statant” that can be applied to any four
legged creature. Blazon also has the attitudes “volant” and “displayed” which can only be applied to
creatures with wings. When writing the production rules for recognising charges, we must ensure that
the grammar will not accept invalid combinations of charge and attitude, e.g. “a lion volant”.
There are a few possible solutions to recognise the unlimited range of charges in the grammar. We could
add a rule that recognises any word (see figure 3.12. This adds ambiguity to the grammar as the rule
word ::= [ A–Z a–z ]+
Figure 3.12: A grammar rule to match any word
will also match words such as “gules” and “bend”. This means the grammar needs to make a decision for
which token to match the input with. This rule also stops us checking whether the attitude applied to the
charge is valid, as mentioned above. An alternative solution is to write rules to recognise the common
charges then dynamically update the grammar. When a user adds a new charge into the database we
could update the grammar to allow them to use the newly added charge.
3.3.5
User interface
Deploying an application to the web makes it accessible to anyone with an internet connection. Webbased applications are platform independent meaning their behaviour does not change between computer
architecture or operating systems. This platform independence means the application only needs to be
compiled and deployed once.
The interface for BlazOnLion will use a form fill-in interaction style. This style of interface should be
familiar to users and is suited to web-based applications. Figure 3.13 shows an example for how the user
interface may look. The interface will have a text box for users to enter Blazon and a panel for displaying
the generated image. There will also be a panel with text boxes for users to add new charges to the
database. When a user clicks “Draw Shield” and “Add Charge”, an asynchronous method call will be
made to a service. The user interface will remain responsive with a progress bar displayed to show the
user that some processing is taking place. When a user opens BlazOnLion the text cursor will focus on
the text box for entering a sentence of Blazon. The enter keyboard key will also be mapped to the “Draw
Shield” button. This allows a user to open BlazOnLion and draw a shield efficiently, without using their
mouse.
If an error occurs when using BlazOnLion, an error message should be displayed to the user. A wireframe
for how an error should look can be seen in figure 3.14. The error should show a simple message stating
23 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 3.13: A wireframe for the user interface of BlazOnLion
what the cause of the error is, with the option to view more details. Adding this extra step hides
complexity from less experienced users, whilst providing technical users more information on the error if
required.
Figure 3.14: A wireframe for an error message in BlazOnLion
Model View Controller
Model View Controller (MVC) is an architectural pattern used to reduce coupling of the model and view
in a software system. The model in this case is the IR of the shield and the view is the user interface
which provides some way of viewing the model. The controller is used to manage user input and change
the state of the underlying model, causing the view to update [21].
The model should be independent from the view. This allows us to make changes to the view, or have
24 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
multiple views, without making changes to the underlying model, supporting adaptability. For example,
it would allow us to generate any type of image from the same model.
3.4
Summary
In this chapter we introduced a list of functional and non-functional requirements, stating that BlazOnLion should be designed to be usable and robust, supporting portability, adaptability, and testability.
We detailed how using a Service-oriented architecture supports these non-functional requirements. We
discussed how the various components of BlazOnLion are designed to meet the objectives set out in section 1.2. We specified the difficulties of recognising Blazon entirely in the grammar and how we hope to
solve them by deferring some validity checks until creation of the IR. We introduced how the fundamentals of object-oriented analysis and design will help to create an adaptable IR and drawing component.
We introduced how the Template Method and Strategy design patterns can be used for by the drawing component to support extensibility. Finally, we described how users will interact with BlazOnLion
and how implementing the Model View Controller pattern as part of the user interface will support the
non-functional requirements.
25 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Chapter 4
Implementation
In this chapter we examine the approach taken in the development of BlazOnLion. We will compare
languages and tools available to develop each component and justify why we chose certain technologies.
Then we will discuss some of the interesting and difficult areas found during the development process.
4.1
Agile approach
In section 1.2 we set out the project objectives with sub-objectives. These sub-objectives were used to
develop the application in an iterative and incremental approach. Each iteration was made up of the
following phases — conception, analysis, design, implementation, testing, refactoring, and deployment.
Conception
We decide which sub-objectives will be completed during the iteration.
Analysis and design
We study the sub-objectives to get a better understanding and plan how to add the new behaviour.
Implementation
During the implementation phase we write the code to add behaviour.
Testing
Throughout implementation we assert the new behaviour by writing unit tests.
Refactoring
At the end of the implementation, we are able to refactor the code1 . After each unit of refactoring
we can check the behaviour remains the same by re-executing unit tests. If a test fails we have
incorrectly altered the external behaviour.
Deployment
At the end of the iteration, we have a prototype application to be deployed. This enables us to
check that user’s needs are being met and adjust the project requirements appropriately.
1 Refactoring is a process by which we restructure code to make it re-usable, remove duplicate code, or improve clarity
without changing its external behaviour [22].
26 of 73
Translating Blazon into Coats of Arms
4.2
4.2.1
Luke Torjussen
Technologies
Programming platform
The requirement for a web-based interface, coupled with previous programming language experience,
highlights PHP or Java as the logical choice.
Java Java, created by Sun Microsystems 2 , is an object-oriented programming language. An objectoriented language allows us to map objects in the domain, in this case shields, into conceptual software
objects. Java source code is compiled into an intermediate bytecode which is interpreted by the Java
Virtual Machine (JVM). The Java API includes a number of user interface toolkits, namely AWT and
Swing, making it simple to add a user interface to applications [23]. There are a number of ways to
deploy Java applications on the web. Java Servlets and JavaServer Pages are server-side components
which interact with HTML based clients. With these technologies code is run on the server side only.
Java applets Applets are Java applications that can be run as part of a web-page or downloaded.
Using applets means all processing takes place within the user’s web browser, leaving no strain on the
server, therefore making it more scalable for many users. Applets typically use Swing user-interfaces
which look non-native. Many modern web browsers, including mobile browsers, lack support for Java
Applets without a third-party plugin. On initial use an applet must start the JVM causing poor startup
performance [24].
Google web toolkit Google Web Toolkit (GWT) is a collection of APIs which allow developers to
build web-based applications written in Java. GWT compiles Java source into optimised JavaScript
to run within a web browser [25]. This allows processing within the web browser, but offers support
for server-side processing via Remote Procedure Calls (GWT-RPC) [26]. A user interface in GWT gets
compiled into HTML so looks native in a web browser. The GWT provides APIs that emulate some of
Java’s runtime libraries, however some classes and methods are not provided [27].
PHP PHP: Hypertext Pre-processor, created by The PHP Group, is a widely used scripting language.
We can embed PHP in HTML to produce dynamic webpages [28]. The language has supported objectoriented programming functionality since version 3.0 and has improved in later versions. PHP source
code is interpreted by the PHP engine on the server side and produces a HTML web-page. This could
put strain on the server as the number of users increased. An advantage of using PHP is that the user
interface would look native in a web browser.
4.2.2
Parser generator
To recognise sentences of Blazon we must select a parser generation framework.
Lex and Yacc Lex generates lexical analysers from regular expressions. The program produced by
Lex mimics a finite state automata matching input strings to tokens [29]. Yacc is used to generate a
parser from a BNF style grammar. Lex and Yacc are well documented and have been ported to support
a number of language runtimes including PHP. They do, however, lack a port for Java.
2 Sun
Microsystems are now part of Oracle Corporation.
27 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
JavaCC The Java Compiler Compiler (JavaCC) is a tool that converts a BNF grammar into a Java
Lexer and Parser. There is limited documentation at the official web pages [30], is not actively developed,
and lacks support for any language other than Java. An advantage of JavaCC is the ability to embed
Java code in the grammar to carry out actions when a grammar rule is matched.
ANTLR ANother Tool for Language Recognition (ANTLR) is actively developed by Terence Parr at
the University of San Francisco. Given a BNF grammar ANTLR can generate a Lexer and Parser in
Java, PHP, and a number of other languages [31]. ANTLR has a range of documentation including a
book written by its creator [32]. Like JavaCC, there is support for embedding source code within the
grammar.
4.2.3
Image format
In order to draw the shield we must choose an appropriate image format.
Scalable Vector Graphics (SVG) SVG is an XML based image format managed by the SVG Working Group [33]. Images in SVG are vector graphics meaning they are described using shapes and lines
rather than a matrix of dots. This allows us to resize an SVG image without losing quality. As SVG
images are XML based we can display them within a web browser. The new HTML5 standard allows
SVG images to be inlined as part of a web page [34].
4.2.4
Choices and justifications
GWT seems the appropriate platform as it allows us to produce a web-based application, supporting the
portability requirement, and uses an object-oriented programming language with which we are already
familiar. Unlike the other platforms considered, GWT provides the choice to process on the client and
server allowing an easy separation of concerns, aiding in the adaptability of components. Google also offers
a deployment infrastructure called the Google App Engine (GAE) which hosts GWT applications [35].
The GAE also provides the Datastore a schema-less object database for storing, querying, and manipulating data via Java Persistence API (JPA) [36]. We can use the Datastore to store references to images
for new charges. SVG images seem an appropriate format as they can be displayed easily as part of a
webpage.
For parser generation, ANTLR is the best choice as it is well documented, has support for Java, and
allows embedding of source code in the grammar.
There is a library available lib-gwt-svg, created by Vectomatic, for drawing SVG images within a GWT
application. The library provides methods to draw SVG images without writing XML [37].
4.3
Interesting aspects of development
In this chapter we will see some aspects during the development of BlazOnLion that were either interesting
or problematic. It details how some of the issues raised in 1.4 were solved and how we were unable to
solve others within the timescale of the project.
28 of 73
Translating Blazon into Coats of Arms
4.3.1
Luke Torjussen
Drawing a varied field
Problem
We saw earlier that a field can be divided into a specified number of sections e.g. “paly of 8”. When
varying the field using a “bend”, “bend sinister”, or “chevron reversed” the number of sections visible
was not the same as was specified.
Point 1: (w, 0)
i×w
, 0
Point 2:
n/
2
(n /2 − i) × h
Point 3:
w,
n/
2
Figure 4.1: Diagram of how the rectangle can be
split into rectangles
Figure 4.2: Formulae for calculating co-ordinates of
the triangles for “bendy”
Figure 4.1 shows how we can draw these variations using triangles. The calculations for finding the
triangle’s co-ordinates are shown in figure 4.2. The three triangles in the bottom left corner can be drawn
using the same co-ordinates but changing Point 1 to (0, h). When we draw these triangles, alternating in
colour, we get 6 evenly sized diagonal stripes across the shield. When we add the shield outline we find
that only 5 of the 6 stripes are visible (see figure 4.3). This is incorrect as we have specified 6 stripes to
be drawn in the shield. We see a similar effect when drawing “bendy sinister” and “chevronny reversed”.
Figure 4.3: Diagram showing how the shield outline hides some of the triangles
29 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Solution
Rather than calculating triangle sizes within the rectangle, we will now use the distance between the top
right corner of the shield and the midpoint of the bottom left arc of the shield outline. Each arc of the
shield outline is drawn as a Bézier curve.
The Bézier curve is specified by the two end points E1 and E2 and two control points C1 and C2 [38].
Figure 4.4 shows how to calculate the co-ordinates for the curve’s midpoint.
X=
3
3
1
1
x1 + x3 + x4 + x2
8
8
8
8
Y =
3
3
1
1
y1 + y3 + y4 + y2
8
8
8
8
Figure 4.4: Equations for calculating the midpoint co-ordinates of a Bézier curve
x1 and y1 are the co-ordinates of point E1 , x2 and y2 are the co-ordinates of point E2
x3 and y3 are the co-ordinates of point C1 , x4 and y4 are the co-ordinates of point C2
Once midpoint M has been calculated we find the distance from M to the top corner using Pythagoras’
theorem 3 . We divide the distance by the number of stripes we want the field to be divided into, and
draw the shield using triangles of increasing size, as shown in figure 4.5. We can use the snippet of code
shown in figure 4.6 to draw the triangles and therefore solve the issue of drawing a varied field.
Figure 4.5: Diagram showing correctly sized triangles for varying the field
3 Pythagoras’ theorem allows us to find the length of the hypoteneus of a right-angled triangle using the lengths of the
other two sides.
30 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
// calculate width of stripe
double stripeWidth = numberOfStripes / distanceFromCornerToCurveMidpoint;
Point topCorner = new Point(shieldWidth, 0); // create Point object for top corner
for (int i = numberOfStripes; i > 0; i−−) {
// calculate co−ordinates for other 2 corners
double triangleHeight = i * stripeWidth;
double triangleSideLength = Math.sqrt(2 * Math.pow(triangleHeight, 2));
Point corner1 = new Point(shieldWidth − triangleSideLength, 0);
Point corner2 = new Point(shieldWidth, triangleSideLength);
Triangle triangle = new Triangle(topCorner, corner1, corner2);
// alternate between tinctures to get alternating coloured stripes
Tincture tincture = isEvenNumber(i) ? tincture1 : tincture2;
drawShape(triangle, tincture);
}
Figure 4.6: Code outlining the algorithm for drawing “bendy of 6”
4.3.2
Specifying the correct number of tinctures for field division
Problem
In section 1.4 we outlined the problem of specifying the correct number of tinctures for a field division,
with an approach elaborated in section 3.3.1.
Solution
In ANTLR we are able to embed Java code into the grammar rules. The code in figure 4.7 shows how
we combined an ANTLR grammar rule with Java source to handle the issue.
some tinctures[Tinctures tinctures, ShieldDivisionType division] returns [Field field] :
{ int count = 0; } // create a counter which increments when we find a tincture
( tincture[tinctures] { count++; } )+
AND // match the word ’and’
tincture[tinctures] { // match a final tincture and increment the counter
count++;
// check the number of tinctures specified was correct
int numberOfTinctures = division.getNumberOfTinctures();
if (numberOfTinctures != count) { // if incorrect, create error and throw exception
diags.add(ShieldDiagnostic.build(LogLevel.ERROR,
‘‘Incorrect number of tinctures specified. The ’’ + division
+ ‘‘ division type only allows the following number of tinctures: ’’
+ numberOfTinctures + ‘‘ but found ’’ + count));
throw new RecognitionException(this.input);
}
$field = FieldImpl.buildDividedField(tinctures, division);
};
Figure 4.7: Code to recognise number of tinctures for a field division
31 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
The grammar rule some tinctures takes a Tinctures object, which keeps a list of the tinctures in use,
and a ShieldDivisionType enum value, to represent how the field has been divided. Whenever we find a
tincture we increment a counter. We are then able to check whether the number of tinctures specified
is the correct number for the given field division. If the correct number have been specified we return
a field object, otherwise we present the user with an error stating that an incorrect number of tinctures
has been given. This solves issue 1 described in section 1.4.
4.3.3
Following the rule of tincture
Problem
In section 1.4 we outlined the problem of ensuring the rule of tincture is followed when there are multiple
charges on the field. We then discussed the details of this issue in section 3.3.1. Grammars are unable
to convey meaning, therefore we need to handle this issue during construction of the IR. BlazOnLion is
unable to handle this issue as the IR only conveys information about the field (its division and tinctures)
and the charges (what they are, their tinctures, and how many there are). The co-ordinate position of
the charges, is only calculated when drawing the shield. This means we lack the information within the
IR to give a solution to this problem. The application is however, able to check whether a sentence of
Blazon follows the rule of tincture for single occurrences of a charge.
Partial Solution
In order to check the rule of tincture we created an enumerated type (enum) which represented the type of
tinctures. The Tincture class has a method named getTinctureType which returns one of the following
enum values:
ˆ COLOUR — any tincture that is of the Colour class will return this value.
ˆ METAL — any tincture that is of the Metal class will return this value.
ˆ OTHER — any other tincture such as a fur, proper, or a combination of tinctures side by side, will
return this value.
We must then check the type of tincture of the field (see code in figure 4.8). If the field has a single
tincture then we return the corresponding enum value. When there are multiple tinctures on the field,
we iterate through the collection of tinctures. If we find two tinctures with different tincture types, e.g.
the field is divided with a colour and a metal, we return the value OTHER, otherwise we return COLOUR or
METAL as appropriate.
public TinctureType getTinctureTypeOfField() {
Iterator<Tincture> iterator = tinctures.getTincturesOnLayer().iterator();
TinctureType firstTinctureType = iterator.next().getTinctureType();
while (iterator.hasNext()) {
TinctureType tinctureType = iterator.next().getTinctureType();
if (tinctureType != firstTinctureType)
return TinctureType.OTHER;
}
return first;
}
Figure 4.8: Code to find the TinctureType of the field
32 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
When the parser recognises a charge it creates an instance of the Charge class. Once the charge object
has been created, the parser calls the method shown in figure 4.9 to test whether the rule of tincture
has been followed. The method takes the tincture of a charge and the tincture type of the field. If the
tincture types are the same, and not of the tincture type OTHER, the rule of tincture has been broken. If
the rule is broken, the parser will create a warning and added to the list of parser errors, to be displayed
on the user interface.
private void checkRuleOfTincture(Tincture chargeTincture, TinctureType fieldTinctureType) {
TinctureType chargeTinctureType = chargeTincture.getTinctureType();
if (fieldTinctureType == chargeTinctureType)
if (chargeTinctureType == TinctureType.COLOUR || chargeTinctureType == TinctureType.METAL)
diags.add(ShieldDiagnostic.build(LogLevel.WARNING, ”You are not obeying the rule of tincture. ”
+ ”You can not put a colour on a colour, or a metal on a metal”));
}
Figure 4.9: Code to check whether the rule of tincture is being followed
Although we have not solved the issue set in section 1.4, we have demonstrated that diagnosing the rule
of tincture is too complex to be handled within the grammar alone.
4.3.4
Drawing multiple charges without overlap
Problem
The area of implementation discussed in this section relates to drawing multiple charges on the shield
(sub-objectives D, F, and G and issue 3). When we draw multiple charges they should not overlap. We
discussed in section 3.3.3 that as the number of charges increases we should reduce their size proportionally.
Partial solution
The application has a number of classes, each responsible for drawing a particular type of charge. The
hierarchy for the charge drawing classes is shown in figure 4.10.
Figure 4.10: Diagram showing hierarchy of charge drawing classes
33 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
The geometric charge drawers are responsible for drawing ordinaries and other shapes with a fixed
position. These charges only appear once so drawing them is straightforward. The mobile charge drawers
are responsible for drawing charges that can change position on the shield. For each of these drawers there
is a method defining how to draw the shape of the charge and methods for calculating its co-ordinates
given the number of occurrences. The abstract SVGMobileChargeDrawer then calls the draw method,
specifying the row and column in which it should be placed. The row and column offsets are calculated
using the number of occurrences and size of the charge. An example of this can be seen in figure 4.11
which shows the rows and columns for drawing “6 roundels”.
Figure 4.11: Diagram showing rows and columns when drawing “6 roundels”
4
In most cases the lowest co-ordinates a charge can be drawn at is point (0, 0), similarly the highest
co-ordinates are (chargewidth, chargeheight). When we charge the shield with a “chief ” or “base”, the
area in which we can draw charges is changed. To handle this, we store the size of the area in which
we can draw. When we add a “chief ” or “base” to a shield we change the co-ordinates of the drawable
area appropriately. Figure 4.12 shows how the area changes when we draw a “bend” with combinations
of “chief ” and “base”.
Figure 4.12: Diagrams showing how charge drawing area changes with presence of “chief ” and “base”
5
In the left-most image, “purpure a bend argent”, the charge drawing area is at its full size. The inner
4 Image
generated by BlazOnLion and amended manually
5 Images
generated by BlazOnLion and amended manually
34 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
left image, “purpure a chief or a bend argent”, shows how adding the chief moves the upper co-ordinates
of the charge drawing area, restricting the “bend” to be drawn within the smaller purple area. The two
right images show similar situations using a “base” alone, and a “chief ” with a “base”.
Although BlazOnLion allows multiple charges to be specified, it lacks the ability to dictate where to
place them, e.g. “in chief ”. The drawing objects are only aware of multiple occurrences of the same
type, resulting in overlap. For example when we ask BlazOnLion to draw “gules 3 roundels argent a lion
rampant or”, the “roundels” overlap with the lion. This can be seen in figure 4.13. This is a limitation
of BlazOnLion and should be addressed in future development.
Figure 4.13: Diagram showing “gules 3 roundels argent a lion rampant or” with charges overlapping6
4.3.5
Creating user friendly error messages
Problem
One of the non-functional requirements set in section 3.1 was error handling. Here we stated that a user
should be made aware when an error occurs. “The error message displayed to a user should be concise,
detailed, and use language appropriate to the user”. When the lexer or parser encounters an error it
throws an exception. Displaying an exception message to a user does not meet the stated requirements.
Partial solution
To gather error messages we have added an error reporting mechanism in the form of the ShieldDiagonstic
class. Each ShieldDiagonstic object has a severity level, to denote how serious an error is, and an error
message, to explain the error that has occurred. The IR of the shield contains a list of ShieldDiagonstic
objects.
As an exception is thrown, or some other event such as not following the rule of tincture occurs, we
create a new ShieldDiagonstic object and add it to the IR. If there is a severe error whilst parsing a
6 Image
generated by BlazOnLion and amended manually. Image of Lion from Wikipedia Attitudes page [7].
35 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
sentence of Blazon, the application creates an InvalidShield object. The methods on the InvalidShield
class provide no behaviour meaning no image is generated by the client; this is known as the Null Object
design pattern [22]. When the client receives the IR, it reports any errors to the user in a dialog box.
The error messages shown to the user are concise but high level. We added a link on the dialog box for
users to view details of an error. Unfortunately the details of errors consist of either an exception or
error message produced by ANTLR. The errors generated by ANTLR are difficult for a typical user to
understand. The error message states which character is unexpected or missing. For example, the invalid
Blazon sentence “a gules” produces the following error message:
line 1:0 no viable alternative at input ’a’
This level of detail is only useful for a user familiar with the parsing process.
The requirement of error handling is only partially met. Producing understandable error messages should
be addressed in future development of BlazOnLion.
4.3.6
Displaying a wait cursor
Problem
As discussed in the requirements section, if a task is long running, a user should be made aware by
displaying some form of wait cursor. In GWT we can access the cursor attribute of the document model7
and change its value to wait, using the code shown in figure 4.14. The effects of this code are inconsistent
across web browsers. We want to ensure the wait cursor is displayed consistently across all web browsers
to follow the requirement of portability.
DOM.setStyleAttribute(RootPanel.get().getElement(), ”cursor”, ”wait”);
Figure 4.14: Code to use a wait cursor in GWT
Solution
GWT allows developers to integrate JavaScript directly into Java source code using the JavaScript Native
Interface (JSNI). A wait cursor written purely in JavaScript should be compatible with all modern web
browsers.
The wait cursor used in BlazOnLion, called a Spinner, is configurable and freely available [39]. We can
encapsulate the native JavaScript code within a Java class called ProgressSpinner. The class contains a
JavaScriptObject field representing the Spinner, and methods to start and stop the Spinner. The code
for this class can be seen in figure 4.15.
Whilst the spinner is displayed the user interface remains responsive. This allows us to meet the performance requirement set in section 3.1.
4.4
Summary
In this chapter we outlined the approach used during the development process of the application. We
then discussed the advantages and disadvantages of various technologies, concluding that the Google
7 The
document model (DOM) is the convention used for representing a HTML document.
36 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
public class ProgressSpinner {
private JavaScriptObject spinner;
public ProgressSpinner() { setUpSpinner(); }
private native void setUpSpinner() /*−{
/* create a new spinner object and assign it to the spinner field */
var opts = { /* options for size and speed of Spinner */ };
[email protected]::spinner = new $wnd.Spinner(opts);
}−*/;
native void stop() /*−{
/* call the stop method on the spinner field */
[email protected]::spinner.stop();
}−*/;
native void start(String elementId) /*−{
/* call the spin method on the spinner field
and display it within the HTML element with the given ID */
[email protected]::spinner.spin($wnd.document.getElementById(elementId));
}−*/;
}
Figure 4.15: JSNI code for controlling the wait cursor
Web Tookit, ANTLR parser generator framework, and SVG images, would be the most appropriate for
producing the application. Finally we studied a number of interesting issues found whilst developing
BlazOnLion and what steps we took to solve them.
37 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Chapter 5
Results
In this chapter we outline the how the final application is used. We will examine an example workflow to
see how a user interacts with the application. At key stages through the workflow we show screenshots
of the user interface.
5.1
Workflow
The standard workflow for using BlazOnLion consists of a single step:
ˆ A user enters a sentence of Blazon and an image of the described shield is displayed.
There are alternative flows that users may follow when using BlazOnLion. Rather than an image being
displayed, the user may be presented with an error because. . .
ˆ . . . BlazOnLion is unable to parse the entered Blazon.
ˆ . . . there is no image present in the database for one of the specified charges.
If no image is found in the database, users can add a new image using the form on the user interface.
Once they have done this the user returns to the standard workflow to generate an image from their
Blazon.
5.2
An example workflow
When a user opens BlazOnLion in their web browser1 they are presented with the startup screen shown
in figure 5.1. There is some introductory text followed by example sentences for users to try. At the
bottom of the page is the main part of the application, which is divided into two panels. The panel on
the left allows users to enter a sentence of Blazon and generate shields. The panel on the right is for
adding new charges to the database.
1 BlazOnLion
is available at http://shielddrawing.appspot.com.
38 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 5.1: Screenshot of BlazOnLion upon startup
39 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
First the user tries drawing the shield for the sentence “gules”. The user enters the sentence into the text
box and clicks the “Draw Shield” button, starting a remote procedure call to the parsing service. Whilst
the client awaits a response, a wait cursor is displayed, as shown in figure 5.2. Once processing has been
completed, the generated image appears on the screen, as shown in figure 5.3.
Figure 5.2: Screenshot of wait cursor whilst
processing the sentence “gules”
Figure 5.3: Screenshot of image generated for the
sentence “gules”
The user may want to add a charge to the shield. The user enters the sentence “gules a lion rampant or”
and click the “Draw Shield” button. BlazOnLion presents the user with an error informing them there
is no image for a “lion rampant or” (see figure 5.4). To resolve this error the user must add a new image
to the database using the panel on the right side of the user interface.
Figure 5.4: Screenshot of error message for a missing charge image
The user enters the type of charge, its attitude, its tincture, and a URL for an image for this charge (see
figure 5.5). The user then clicks the “Add Charge to Database” button. The application will display a
message notifying the user that the image was added successfully. Now the image has been added, the
user can draw the shield for “gules a lion rampant or”. Once again, the user clicks the “Draw Shield”
button and the application generates the image seen in figure 5.6.
40 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 5.5: Screenshot of inputting data for new
charge image
Figure 5.6: Screenshot of image generated for the
sentence “gules a lion rampant or”
5.3
Summary
In this chapter we outlined how a user interacts with BlazOnLion in a typical workflow. We saw how
a user can generate an image for a sentence of Blazon, and how to add an image for a charge that is
missing from the database.
41 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Chapter 6
Testing and Evaluation
In this chapter we shall discuss how BlazOnLion was tested. We see how unit tests were used to assert
behaviour of each part of the application, and how well we satisfied the objectives set in section 1.2.
6.1
Unit testing
Throughout the project, unit tests were written using the JUnit framework [40] as part of the agile
development approach discussed in section 4.1. Unit testing is a form of white box testing that directly
tests the source code to assess its behaviour. At each stage of development unit tests were written to
confirm the expected behaviour of the code. If any tests failed, the code was changed to correct the
behaviour. The tests allowed refactoring of code to improve clarity and design.
We can analyse how much code is being executed whilst testing using code coverage statistics [41]. Code
coverage statistics report which instructions are executed during tests and therefore show which sections
of code are untested. Table 6.1 shows a summary of the code coverage statistics for BlazOnLion1 . The
statistics show that although the Grammar and IR components are tested thoroughly, only 43% of the
application’s Java code has been tested due to the low coverage of the Drawing and User Interface
components.
Component
Lines of Java Code
Number of Tests
Coverage (%)
Grammar
3,745
458
96.6%
Intermediate Representation
1,374
449
99.2%
Drawing & User Interface
4,132
109
6.8%
Total
9,251
1016
43.1%
Table 6.1: Table showing code coverage statistics
1 All
statistics exclude blank lines of source code.
42 of 73
Translating Blazon into Coats of Arms
6.1.1
Luke Torjussen
Testing the grammar
ANTLR provides a testing framework called gUnit [42] for testing grammars. gUnit lacks the ability to
test parser methods requiring parameters. As ANTLR generates Java classes for the lexer and parser we
were able to test the generated classes using JUnit in the usual way. Writing tests for lexer rules using
JUnit is non-obvious so they were written using gUnit and then converted by ANTLR into JUnit tests.
6.1.2
Testing the IR
The tests for the IR were written using JUnit with Hamcrest matchers [43]. To assert the return values
of methods we needed to override the equals method in each class of the IR. The equals methods were
implemented to be reflexive, symmetric, transitive, and consistent [44]. The IR is the most thoroughly
tested component as it is used throughout the application. If an error occurs whilst generating a shield
IR, the generated image will not represent the shield intended.
6.1.3
Testing the drawing component
There is a significant lack of unit testing for the drawing and user interface components of the application.
The Google Web Toolkit provides an extension of JUnit for testing GWT applications. The most appropriate way to test each class of the drawing component would be to compare the generated SVG XML
code with what was expected. During development we were unable to set up the correct environment to
run GWT tests, meaning we were unable to run tests for this component. If future work was undertaken,
adding tests for this component would be a priority.
6.1.4
Summary
Unit testing has allowed us to assess the behaviour of each component. The high code coverage of the
Grammar and IR components means we could re-use them in another application with a high level of
confidence that they work. The next section tests how well they work as an integrated system.
6.2
Success criteria
Throughout development of BlazOnLion, we created a corpus of Blazon sentences and corresponding
shields. In this section, we compare the output of BlazOnLion with the expected image from the corpus.
The comparison of images allows us to evaluate the completeness of the application. We have chosen
a random sentence sample from the corpus of varying complexities. If the image generated differs from
what is expected we will analyse why it has happened.
6.2.1
Plain field
“Gules”
The sentence “gules” describes a red field with no charges. Figure 6.1 shows the expected output. The
actual image generated by BlazOnLion, shown in figure 6.2, has some minor differences to what was
expected. The shade of red used differs as does the shape of the shield. These minor differences can be
ignored because, as discussed in section 2.2.8, these details are left to artistic licence and will be ignored
for the rest of the tests.
43 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 6.1: Expected image for “Gules” [45]
Figure 6.2: Generated image for “Gules”
“Erminois”
The sentence “erminois” describes a yellow field with black ermine spots. Figure 6.3 shows the expected
output. The actual image generated by BlazOnLion, shown in figure 6.4, uses larger ermine spots than
in the expected image. This is a minor detail left to the artist.
Figure 6.3: Expected image for “Erminois” [46]
6.2.2
Figure 6.4: Generated image for “Erminois”
Divided field
“Per pale gules and argent”
The sentence “per pale gules and argent” describes a field parted vertically with a red left hand side and
silver right hand side. Figure 6.5 shows the expected output. The actual image generated by BlazOnLion,
shown in figure 6.6, matches the expected image.
44 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 6.5: Expected image for “Per pale gules and
argent” [47]
Figure 6.6: Generated image for “Per pale gules
and argent”
“Lozengy argent and gules”
The sentence “lozengy argent and gules” describes a field of lozenges (diamond shapes) alternating between silver and red. Figure 6.7 shows the expected output. In the expected image the top line of
lozenges, that are cut in half, are tinctured “argent”. In the generated image, shown in figure 6.8 the
top line of lozenges are tinctured “gules”. In this example BlazOnLion is incorrect, however the effort
needed to correct this would be minimal.
Figure 6.7: Expected image for “Lozengy argent
and gules” [48]
Figure 6.8: Generated image for “Lozengy argent
and gules”
“Sable semé of plates”
The sentence “sable semé of plates” describes a black field with many silver circles distributed evenly
across it. Figure 6.9 shows the expected output. When we pass this sentence to BlazOnLion an error
is thrown. The application is unable to recognise the term semé or “plate”. To resolve the issue of
understanding “plate”, we need the parsing component to recognise “plate” in the same way as “roundel
argent”. In other words, when recognising a charge, either look for a charge followed by a tincture, or
45 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
look for a pre-tinctured charge such as a “plate”. Drawing shields for sentences containing semé should
be straightforward as it involves repeating an image or shape across the field.
Figure 6.9: Expected image for “Sable semé of plates” [49]
6.2.3
Single geometric charge
“Argent a saltire azure”
The sentence “argent a saltire azure” describes a silver field with a blue diagonal cross. Figure 6.10
shows the expected output. The actual image generated by BlazOnLion, shown in figure 6.11, has a
minor difference to what was expected. We see the size of the “saltire” differs, but there is no correct
size for drawing this ordinary. The differences once again are due to artistic licence and can be ignored.
Figure 6.10: Expected image for “Argent a saltire
azure” [50]
46 of 73
Figure 6.11: Generated image for “Argent a saltire
azures”
Translating Blazon into Coats of Arms
Luke Torjussen
“Per pall sable gules and or a chevron reversed argent”
The sentence “per pall sable gules and or a chevron reversed argent” describes a shield with a field divided
by a vertical line, red on the left, yellow on the right, with a black triangle at the top. The shield is
charged with a white chevron drawn from the top, pointing to the centre. Figure 6.12 shows the expected
output. The actual image generated by BlazOnLion, shown in figure 6.13, has some minor differences
to what was expected. In the generated image the chevron falls along the line of division, but in the
expected image the red and yellow from the field are visible above the chevron. Other images found
during research show that a “chevron” drawn on a field divided “per pall” should be depicted in the same
way as BlazOnLion generates [51].
Figure 6.12: Expected image for “Per pall sable
gules and or a chevron reversed argent” [13]
Figure 6.13: Generated image for “Per pall sable
gules and or a chevron reversed argent”
“Or a roundel azure”
The sentence “or a roundel azure” describes a yellow field charged with a blue circle. Figure 6.14 shows
the expected output. The actual image generated by BlazOnLion, shown in figure 6.15, matches the
expected image.
Figure 6.14: Expected image for “Or a roundel
azure” [13]
47 of 73
Figure 6.15: Generated image for “Or a roundel
azure”
Translating Blazon into Coats of Arms
6.2.4
Luke Torjussen
Multiple geometric charges
“Gules three bezants”
The sentence “gules three bezants” describes a red field charged with three yellow circles. Figure 6.16
shows the expected output. BlazOnLion is unable to handle pre-tinctured charges, so when we give this
sentence the application displays an error. Another name for a “bezant” is a “roundel or”. When we
change “bezants” to “roundels or” in the test sentence, the application generated the image shown in
figure 6.17. The generated and expected images now match.
Figure 6.16: Expected image for “Gules three
bezants” [52]
Figure 6.17: Generated image for “Gules three
roundels or”
“Azure a chevron or with three stars the same”
The sentence “azure a chevron or with three stars the same” describes a blue field charged with 3 yellow
stars and a yellow chevron. Figure 6.18 shows the expected output. When given this sentence BlazOnLion
fails as it does not understand “with” or “the same”. We should be able to use “the same” to state that
a charge is tinctured using the same tincture as the previous charge. When we remove the word “with”,
and replace “the same” with “or”, the application generates the image shown in figure 6.19. The “stars”
in the generated image have six points whilst those in the expected image have only five. In heraldry
there is no default number of points a “star” should have. In the generated image, the bottom “star”
incorrectly overlaps with the “chevron”.
48 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure 6.18: Expected image for “Azure a chevron
or with three stars the same” [53]
6.2.5
Figure 6.19: Generated image for “Azure a chevron
or three stars or”
Single advanced charge
“Azure a griffin rampant or langued and armed gules”
The sentence “azure a griffin rampant or langued and armed gules” describes a blue field charged with a
griffin. The griffin should be yellow, have its foreclaws raised, with a red tongue and claws. Figure 6.20
shows the expected output. When we give this sentence to the application it produces an error. This
error occurs because of how we specified the grammar, although it should have been accepted. When we
replace “langued and armed gules” with “langued gules and armed gules” the application generates the
image shown in figure 6.21. This image matches the expected image.
Figure 6.20: Expected image for “Azure a griffin
rampant or langued and armed gules” [54]
49 of 73
Figure 6.21: Generated image for “Azure a griffin
rampant or langued gules and armed gules”
Translating Blazon into Coats of Arms
Luke Torjussen
“Or an anchor sable”
The sentence “or an anchor sable” describes a yellow field charged with a black anchor. Figure 6.22 shows
the expected output. When we pass this sentence to BlazOnLion an error is thrown as it is unaware of
a charge named “anchor”. This is due to the issue discussed in section 3.3.4.
Figure 6.22: Expected image for “Or an anchor sable” [55]
“Or a double-headed eagle displayed sable membered and beaked gules”
The sentence “or a double-headed eagle displayed sable membered and beaked gules” describes a yellow
field charged with a black eagle with two heads, red claws, and a red beak. Figure 6.23 shows the expected
output. When we pass this sentence to BlazOnLion an error is thrown as it is unaware of a charge named
“double-headed eagle”. This is due to the issue discussed in section 3.3.4.
Figure 6.23: Expected image for “Or a double-headed eagle displayed sable membered and beaked gules”
[56]
50 of 73
Translating Blazon into Coats of Arms
6.2.6
Luke Torjussen
Multiple advanced charges
“Argent two lions combatant gules”
The sentence “argent two lions combatant gules” describes a silver field charged with two red lions rampant
facing each other. Figure 6.24 shows the expected output. The attitude “combatant” is unrecognised by
BlazOnLion, resulting in an error. This is related to the issue discussed in section 3.3.4.
Figure 6.24: Expected image for “Argent two lions combatant gules” [57]
“Azure 6 lions rampant or langued gules”
The sentence “azure 6 lions rampant or langued gules” describes a blue field charged with six lions.
The lions should be yellow, with a red tongue, and have their foreclaws raised. Figure 6.25 shows the
expected output. The image generated by BlazOnLion, see figure 6.26, matches the expected image with
one significant difference. The lions in the generated image are small to the extent that it is difficult to
identify them as lions. This is related to the issue discussed in section 3.3.3. As the number of charges
increases they must reduce in size to avoid overlapping. BlazOnLion is decreasing the size of charges too
much, meaning when multiple charges are specified they are too small.
Figure 6.25: Expected image for “Azure 6 lions
rampant or langued gules” [3]
51 of 73
Figure 6.26: Generated image for “Azure 6 lions
rampant or langued gules”
Translating Blazon into Coats of Arms
6.2.7
Luke Torjussen
Combination of geometric and advanced charges
From the research carried out, the combination of multiple charges is rarely seen without specification of
a charges placement. For example, “Azure, a chevron between three eagles displayed or”, states we have
a chevron with three eagles placed around it. Omitting the word “between” hides the detail for where
the chevron should be placed. As BlazOnLion is unable to specify charge positions, it draws overlapping
charges. The ability for BlazOnLion to draw multiple types has been added but will only be utilised once
charge positioning is supported.
6.2.8
Other objectives
Due to time constraints, BlazOnLion was unable to meet some sub-objectives set out in section 1.2.
BlazOnLion is unable to recognise or generate images for shields. . .
H . . . with counter-changed charges,
I . . . the line of partition is varied,
J . . . with charge positioning specified,
K . . . that have been marshalled.
For this reason, tests for these objectives have been omitted.
6.3
Evaluation
In section 3.1 we set out which sub-objectives we felt BlazOnLion must, should, and would like to meet.
From the testing we have just seen, we can evaluate how well BlazOnLion has met the objectives. Table 6.2
shows the results of this evaluation.
Although three of the four could have sub-objectives were not implemented, we were able to attempt subobjective G. We also implemented two of the three should have sub-objectives. These were incomplete
due to time constraints and dependencies on other sub-objectives, which were unnoticed at the projects
conception. Ignoring the issue of the unlimited range of charges, all must have sub-objectives were
completed successfully.
6.4
Summary
In this section we saw how the components of BlazOnLion were tested individually and as an integrated
system. We then evaluated its performance using the objectives and requirements set in earlier sections.
We see that although areas of Blazon remain unhandled, the application succeeded for a number of tests.
52 of 73
Translating Blazon into Coats of Arms
Sub-objective
Luke Torjussen
Priority
Level of Completion
A — Plain field
Must have
Complete.
B — Divided field
Must have
Partially Complete. The application is unable to represent fields using semé.
C — Single geometric charge
Must have
Partially Complete. There is a limited range of
charges available. We are also unable to represent charges which are pre-tinctured e.g. “bezant”,
“plate”.
Should have
Partially Complete. There should be a more robust
approach for resizing and placing charges to avoid
overlap.
Must have
Partially Complete. There should be better support
for a wide range of charges and attitudes.
F — Multiple advanced charges
Should have
Partially Complete. There should be a more robust
approach for resizing and placing charges to avoid
overlap.
G — Combination of charges
Could have
Partially Complete. In order for this to be done correctly we need to support sub-objective J.
H — Counter-changing
Could have
Not implemented due to time constraints.
I — Lines of partition
Should have
Not implemented due to time constraints.
J — Charge positioning
Could have
Not implemented due to time constraints.
K — Marshalling
Could have
Not implemented due to time constraints.
D — Multiple geometric charges
E — Single advanced charge
Table 6.2: Table showing evaluation of BlazOnLion against sub-objectives
53 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Chapter 7
Conclusion
Over the course of this project we have seen that it is possible, to some extent, to recognise sentences
of Blazon using a grammar, represent the described shield in some intermediate representation, and
generate an image from the representation. The application, BlazOnLion, was able to meet all of the
non-functional requirements and all of the high priority functional requirements. Some requirements
remain unmet due to time constraints. If future work was done, there are no obvious issues that would
prevent all the requirements being met.
During development of this project we discovered some problem areas of recognising Blazon using a
grammar. We also saw the issue of the unlimited range of charges and how this makes both recognising
Blazon and drawing images difficult.
7.1
Future work
If future work were to be undertaken, we may replace the parser generated by ANTLR, with a manually
written one. This was not considered during conception of the project, but would give us more flexibility
in creating error messages, an issue encountered with ANTLR.
When a charge is added to the database, we could ask whether it is a beast, bird, object etc. to find
which attitudes can be applied to it. This, combined with the new parser would aid with the handling
of the unlimited range of charges, as the parser could query the database to match charges and their
attitudes.
The ability to specify charge positioning would become a priority, as it would allow us to improve the
drawing of multiple charges without overlap. We should also add unit testing to the drawing component
to ensure correctness and robustness.
7.2
Personal development
Prior to this project we had no knowledge of Blazon, it has now become an area of personal interest.
It has developed a number of transferable skills, including time management, research management,
and planning. A number of technologies were also learnt, including the Google Web Toolkit, ANTLR
grammars, and object databases.
54 of 73
Translating Blazon into Coats of Arms
7.3
Luke Torjussen
Summary of report
Overall this has been an enjoyable and successful research project. This report outlines the effort taken
to design and produce BlazOnLion, and the difficulties in recognising natural language and generating
images using software. BlazOnLion is available online1 and we hope to interest computer scientists,
linguists, and historians alike.
1 It
can be found at http://shielddrawing.appspot.com.
55 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Bibliography
[1] M. Pastoureau, Heraldry Its Origins and Meaning. Thames and Hudson, 1997.
[2] T. Woodcock and J. M. Robinson, The Oxford Guide to Heraldry. Oxford University Press, 2001.
[3] “International Heraldry & Heralds.” http://www.internationalheraldry.com/. Accessed on April
2, 2012.
[4] “It’s Nice That.” http://www.itsnicethat.com. Accessed on April 2, 2012.
[5] “Arms of Dalrymple of Woodhead, Scotland.” http://upload.wikimedia.org/wikipedia/
commons/6/6a/Rustre_dalrymple_wiki.jpg. Accessed on October 11, 2011.
[6] “Variation of the Field.” http://en.wikipedia.org/wiki/Variation_of_the_field. Accessed on
March 29, 2012.
[7] “Charge.” http://en.wikipedia.org/wiki/Charge_(heraldry). Accessed on March 24, 2012.
[8] “The University of Warwick — Crest.” http://www2.warwick.ac.uk/services/communications/
corporate/core/crest/. Accessed on March 27, 2012.
[9] N. Chomsky, “Three models for the description of language,” IRE Transactions on Information Theory, vol. 2, pp. 113–124, 1956. http://www.chomsky.info/articles/195609--.pdf – last visited
14th January 2009.
[10] “BNF and EBNF: What are they and how do they work?.” http://www.garshol.priv.no/
download/text/bnf.html. Accessed on March 26, 2012.
[11] A. Schalk, “COMP11212 Fundamentals of Computation, Part 1: Formal Languages.” Accessed on
March 25, 2012.
[12] “The Medieval Shield Designer.” http://www.btinternet.com/~timeref/heraldry_tincture.
htm. Accessed on March 25, 2012.
[13] “pyBlazon.” http://web.meson.org/pyBlazon. Accessed on March 25, 2012.
[14] A. Dix, J. Finlay, G. D. Abowd, and R. Beale, Human Computer Interaction. Prentice Hall, 2003.
[15] “JAVASOFT SHIPS JAVA 1.0.” http://web.archive.org/web/20080205101616/http://www.
sun.com/smi/Press/sunflash/1996-01/sunflash.960123.10561.xml. Accessed on March 27,
2012.
[16] A. Hunt and D. Thomas, The Pragmatic Programmer. Pragmatic Bookshelf, 1999.
[17] E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable ObjectOriented Software. Addison-Wesley, 1994.
[18] C. Larman, Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design
and Iterative Development. Prentice Hall, 2004.
56 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
[19] R. C. Martin, D. Riehle, and F. Buschmann, eds., Pattern languages of program design 3. Boston,
MA, USA: Addison-Wesley Longman Publishing Co., Inc., 1997.
[20] R. C. Martin, Agile Software Development, Principles, Patterns, and Practices. Prentice Hall, 2002.
[21] I. Sommerville, Software Engineering 8th Edition. Addison-Wesley, 2007.
[22] M. Fowler, Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999.
[23] “Java Language Specification.” http://docs.oracle.com/javase/specs/jls/se7/jls7.pdf. Accessed on April 22, 2012.
[24] “Java Applets.” http://www.freejavaguide.com/java_applet.html. Accessed on March 26, 2012.
[25] “Google Web Toolkit.” https://developers.google.com/web-toolkit/overview. Accessed on
March 26, 2012.
[26] “Google Web Toolkit — Communicate with a Server.” https://developers.google.com/
web-toolkit/doc/latest/DevGuideServerCommunication. Accessed on March 26, 2012.
[27] “Google Web Toolkit — JRE Emulation Reference.” https://developers.google.com/
web-toolkit/doc/latest/RefJreEmulation. Accessed on March 26, 2012.
[28] “PHP Manual.” http://www.php.net/manual/en/index.php. Accessed on March 26, 2012.
[29] “Lex Theory.” http://epaperpress.com/lexandyacc/thl.html. Accessed on March 26, 2012.
[30] “Java Compiler Compiler—(JavaCC—) — The Java Parser Generator.” http://javacc.java.net.
Accessed on March 25, 2012.
[31] “ANother Tool for Language Recognition.” http://www.antlr.org. Accessed on March 25, 2012.
[32] T. Parr, The Definitive ANTLR Reference: Building Domain-Specific Languages. Pragmatic Bookshelf, 2007.
[33] “Scalable Vector Graphics (SVG).” http://www.w3.org/Graphics/SVG/. Accessed on April 6, 2012.
[34] “Inline SVG in HTML5 and XHTML.” http://dev.w3.org/SVG/proposals/svg-html/
svg-html-proposal.html. Accessed on April 6, 2012.
[35] “Google App Engine.” http://code.google.com/appengine/. Accessed on March 26, 2012.
[36] “Datastore Overview.” https://developers.google.com/appengine/docs/java/datastore/
overview. Accessed on April 5, 2012.
[37] “lib-gwt-svg.” http://www.vectomatic.org/libs/lib-gwt-svg. Accessed on April 6, 2012.
[38] J. Kennedy, “A Brief Introduction To Bezier Curves.” Accessed on September 1, 2011.
[39] “spin.js.” http://fgnass.github.com/spin.js/. Accessed on April 7, 2012.
[40] “Junit.” http://junit.org/. Accessed on 19 April, 2012.
[41] J. Smart, Java Power Tools. O’Reilly Series, O’Reilly Media, 2008.
[42] “Gunit — grammar unit testing.” http://www.antlr.org/wiki/display/ANTLR3/gUnit+-+
Grammar+Unit+Testing. Accessed on 19 April, 2012.
[43] “Hamcrest.” http://code.google.com/p/hamcrest/. Accessed on 19 April, 2012.
[44] J. Bloch, Effective Java. Addison-Wesley Java series, Addison-Wesley, 2008.
[45] “Blason vide 3d.” http://upload.wikimedia.org/wikipedia/commons/thumb/9/94/Blason_
Vide_3D.svg/200px-Blason_Vide_3D.svg.png. Accessed on 18 April, 2012.
57 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
[46] “Shield erminios.” http://upload.wikimedia.org/wikipedia/commons/thumb/7/76/Shield_
erminois.svg/200px-Shield_erminois.svg.png. Accessed on 18 April, 2012.
[47] “Party per pale demo.” http://upload.wikimedia.org/wikipedia/commons/thumb/6/67/Party_
per_pale_demo.svg/200px-Party_per_pale_demo.svg.png. Accessed on 18 April, 2012.
[48] “Lozengy demo.” http://upload.wikimedia.org/wikipedia/commons/thumb/9/9d/Lozengy_
demo.svg/218px-Lozengy_demo.svg.png. Accessed on 18 April, 2012.
[49] “Punchardon.” http://www.briantimms.net/rolls_of_arms/images_rolls/Punchardon.gif.
Accessed on 18 April, 2012.
[50] “General armory alderford.” http://generalarmory.wikia.com/wiki/Alderford. Accessed on 18
April, 2012.
[51] “Khovrino
municipal
district.”
http://www.mos.ru/en/about/symbols/divisions/sao/
hovrino/. Accessed on 18 April, 2012.
[52] “Blason montrodat.” http://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Blason_
Montrodat.svg/200px-Blason_Montrodat.svg.png. Accessed on 18 April, 2012.
[53] “Blason ville fr echalas rhône.” http://upload.wikimedia.org/wikipedia/commons/thumb/
d/d6/Blason_ville_fr_Echalas_%28Rh%C3%B4ne%29.svg/200px-Blason_ville_fr_Echalas_
%28Rh%C3%B4ne%29.svg.png. Accessed on 18 April, 2012.
[54] “Blason saint brieuc.” http://img2.tfd.com/wiki/3/30/545px-Blason_Saint-Brieuc.svg.png.
Accessed on 18 April, 2012.
[55] “Blason famille de la bletonniere.” http://upload.wikimedia.org/wikipedia/commons/thumb/
0/07/Blason_Famille_de_la_Bl%C3%A9tonni%C3%A8re.svg/200px-Blason_Famille_de_la_Bl%
C3%A9tonni%C3%A8re.svg.png. Accessed on 18 April, 2012.
[56] “Balogh.” http://upload.wikimedia.org/wikipedia/commons/2/27/Balogh.png. Accessed on
18 April, 2012.
[57] “Blason ville fr plaisance du gers.” http://en.wikipedia.org/wiki/Attitude_(heraldry). Accessed on 18 April, 2012.
58 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Appendix A
Charge Layout
All images shown in this appendix were generated by pyBlazon(http://web.meson.org/blazonserver/).
Figure A.1: “Or a roundel gules”
Figure A.2: “Or a roundel azure in chief ”
Figure A.3: “Or 2 roundels sable”
Figure A.4: “Or 2 roundels gules in base”
59 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure A.5: “Or 3 roundels vert”
Figure A.6: “Or 3 roundels vert in pale”
Figure A.7: “Or 4 roundels purpure”
Figure A.8: “Or 4 roundels purpure 3 and 1”
Figure A.9: “Or 4 roundels azure in bend”
Figure A.10: “Or 4 roundels purpure in fess”
60 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Appendix B
Attitudes
All images shown in this appendix were copied from http://en.wikipedia.org/wiki/Attitude_(heraldry).
Figure B.1: Attitude: “rampant”
Figure B.2: Attitude: “rampant guardant”
Figure B.3: Attitude: “rampant reguardant”
Figure B.4: Attitude: “statant”
61 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Figure B.5: Attitude: “dormant”
Figure B.6: Attitude: “couchant”
Figure B.7: Attitude: “courant”
Figure B.8: Attitude: “salient”
Figure B.9: Attitude: “passant”
Figure B.10: Attitude: “sejant”
62 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
Appendix C
ANTLR Grammar
grammar Blazon;
options {
language = Java;
}
@lexer::header {
package blazon.server.grammar;
import blazon.shared.shield.diagnostic.ShieldDiagnostic;
import blazon.shared.shield.diagnostic.ShieldDiagnostic.LogLevel;
}
@lexer::members {
public BlazonLexer(CharStream input, List<ShieldDiagnostic> diags) {
this(input, new RecognizerSharedState(), diags);
}
public BlazonLexer(CharStream input, RecognizerSharedState state, List<ShieldDiagnostic> diags) {
super(input, state);
this.diags = diags;
}
private List<ShieldDiagnostic> diags;
@Override
public void recover(RecognitionException re) {
int currentPosition = re.charPositionInLine;
char charAtCurrentPosition = input.substring(currentPosition, currentPosition).toCharArray()[0];
int valueOfCharacter = Character.getNumericValue(charAtCurrentPosition);
while (−−currentPosition >= 0 && valueOfCharacter != −1) {
input.seek(currentPosition);
charAtCurrentPosition = input.substring(currentPosition, currentPosition).toCharArray()[0];
valueOfCharacter = Character.getNumericValue(charAtCurrentPosition);
}
currentPosition++;
StringBuilder sb = new StringBuilder();
sb.append(”The application does not recognise the word ’”);
do {
63 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
input.seek(++currentPosition);
charAtCurrentPosition = input.substring(currentPosition, currentPosition).toCharArray()[0];
sb.append(charAtCurrentPosition);
valueOfCharacter = Character.getNumericValue(charAtCurrentPosition);
} while (currentPosition < input.size() && valueOfCharacter != −1);
sb.append(”’”);
diags.add(ShieldDiagnostic.build(LogLevel.ERROR, sb.toString()));
input.consume();
}
}
@header {
package blazon.server.grammar;
import blazon.shared.shield.*;
import blazon.shared.shield.charges.*;
import blazon.shared.shield.ShieldDivision.ShieldDivisionType;
import blazon.shared.shield.diagnostic.ShieldDiagnostic;
import blazon.shared.shield.diagnostic.ShieldDiagnostic.LogLevel;
import blazon.shared.shield.tinctures.*;
import blazon.shared.numberconversion.WordToNumberConverter;
import java.util.Map;
import java.util.HashMap;
}
@members {
public BlazonParser(TokenStream input, List<ShieldDiagnostic> diags) {
this(input, new RecognizerSharedState(), diags);
}
public BlazonParser(TokenStream input, RecognizerSharedState state, List<ShieldDiagnostic> diags) {
super(input, state);
this.diags = diags;
}
private WordToNumberConverter converter = new WordToNumberConverter();
private List<ShieldDiagnostic> diags;
private void diagnoseRuleOfTincture(Tincture t, TinctureType underLayerTinctureType) {
TinctureType thisTinctureType = t.getTinctureType();
if (underLayerTinctureType == thisTinctureType) {
if (thisTinctureType == TinctureType.COLOUR || thisTinctureType == TinctureType.METAL) {
diags.add(ShieldDiagnostic.build(LogLevel.WARNING, ”You are not obeying the rule of tincture. ”
+ ”You can not put a colour on a colour, or a metal on a metal”));
}
}
}
private String checkForPlurals(String text, int number) {
if (number > 1) {
if (!text.endsWith(”s”)) {
diags.add(ShieldDiagnostic.build(LogLevel.WARNING,
”You have specified that there is more than one of a charge, but not used the plural. ”
+ ”Changing ’” + text + ”’ to ’” + text + ”s’.”));
} else {
text = text.substring(0, text.length() − 1);
}
64 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
} else if (number == 1) {
if (text.endsWith(”s”)) {
text = text.substring(0, text.length() − 1);
diags.add(ShieldDiagnostic.build(LogLevel.WARNING,
”You have specified that there is only one of a charge, but used the plural. ”
+ ”Changing ’” + text + ”s’ to ’” + text + ”’.”));
}
}
return text;
}
private boolean startsWithAVowel(String word) {
return word.startsWith(”a”) || word.startsWith(”e”) || word.startsWith(”i”)
|| word.startsWith(”o”) || word.startsWith(”u”);
}
private int convertNumber(String numberWords) throws RecognitionException {
try {
if (numberWords.equals(”a”) || numberWords.equals(”an”)) {
return 1;
}
return converter.convert(numberWords);
} catch (Exception e) {
diags.add(ShieldDiagnostic.build(LogLevel.ERROR, ”Unable to convert ’”
+ numberWords + ”’ into an integer. Caught: ” + e));
throw new RecognitionException(this.input);
}
}
@Override
public void emitErrorMessage(String msg) {
diags.add(ShieldDiagnostic.build(LogLevel.ERROR, msg));
}
protected void mismatch(IntStream input, int ttype, BitSet follow) throws RecognitionException {
throw new MismatchedTokenException(ttype, input);
}
public Object recoverFromMismatchedSet(IntStream input, RecognitionException e, BitSet follow)
throws RecognitionException {
throw e;
}
public List<ShieldDiagnostic> getDiagnostics() {
return diags;
}
}
@rulecatch {
catch (RecognitionException re) {
throw re;
}
}
shield returns [Shield s] :
{
String blazon = input.toString();
65 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
}
field {
$s = ShieldImpl.build($field.field, blazon);
}
(
charges[$field.field.getTinctureTypeOfLayer()] {
$s.addCharges($charges.charges);
}
)*
EOF
{
$s.addDiagnostics(diags);
};
catch [RecognitionException e] {
displayRecognitionError(this.getTokenNames(), e);
return InvalidShield.build(diags);
}
field returns [Field field] :
{
Tinctures tinctures = new Tinctures();
}
(
div {
ShieldDivisionType division = $div.division;
}
some tinctures[tinctures, division] {
$field = $some tinctures.layer;
}
|
tincture or fur[tinctures] ’plain’? {
$field = FieldImpl.buildUndividedShieldLayer(tinctures);
}
);
charges[TinctureType underLayerTinctureType] returns [List<Charge> charges] :
{
Tinctures tinctures = new Tinctures();
$charges = new ArrayList<Charge>();
}
(
DETERMINER single geometric charge[tinctures, underLayerTinctureType] {
if ($single geometric charge.charge != null) {
$charges.add($single geometric charge.charge);
if (”a”.equals($DETERMINER.text)) {
String chargeName = $single geometric charge.charge.getName().toString().toLowerCase();
if (startsWithAVowel(chargeName)) {
diags.add(ShieldDiagnostic.build(LogLevel.WARNING, ”You have asked for the charge ’”
+ $DETERMINER.text + ” ” + chargeName
+ ”’. A charge starting with a vowel should be preceded by ’an’ i.e. ’an ”
+ chargeName + ”’.”));
}
} else if (”an”.equals($DETERMINER.text)) {
String chargeName = $single geometric charge.charge.getName().toString().toLowerCase();
if (!startsWithAVowel(chargeName)) {
diags.add(ShieldDiagnostic.build(LogLevel.WARNING, ”You have asked for the charge ’”
+ $DETERMINER.text + ” ” + chargeName
66 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
+ ”’. A charge starting with a consonants should be preceded by ’a’ i.e. ’a ”
+ chargeName + ”’.”));
}
}
}
}
|
geometricCount=number digits or words multiple geometric charges[tinctures, underLayerTinctureType,
convertNumber($geometricCount.text)] {
if ($multiple geometric charges.charges != null) {
$charges.addAll($multiple geometric charges.charges);
}
}
|
advancedCount=number digits or words advanced charge[tinctures, underLayerTinctureType,
convertNumber($advancedCount.text)] {
if ($advanced charge.charges != null) {
$charges.addAll($advanced charge.charges);
}
}
);
single geometric charge[Tinctures tinctures, TinctureType underLayerTinctureType]
returns [GeometricCharge charge] :
ord = ( ORDINARY DIV | OTHER ORDINARY | SUBORDINARY DIV | SUBORDINARY )
{
String text = $ord.text;
}
(
MODIFIER {
text += ” ” + $MODIFIER.text;
}
)?
t=tincture or fur[tinctures] {
diagnoseRuleOfTincture(t, underLayerTinctureType);
$charge = GeometricCharge.build(text, t, diags);
};
multiple geometric charges[Tinctures tinctures, TinctureType underLayerTinctureType, int number]
returns [List <Charge> charges] :
ords = ( SUBORDINARY MULTIPLE | MOBILE CHARGE )
{
String text = checkForPlurals($ords.text, number);
}
(
MODIFIER {
text += ” ” + $MODIFIER.text;
}
)?
t=tincture or fur[tinctures] {
diagnoseRuleOfTincture(t, underLayerTinctureType);
$charges = new ArrayList<Charge>();
for (int i = 0; i < number; i++) {
Charge charge = GeometricCharge.build(text, t, diags);
$charges.add(charge);
}
};
67 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
advanced charge[Tinctures tinctures, TinctureType underLayerTinctureType, int number]
returns [List <AdvancedCharge> charges] :
( beast = (BEAST | WINGED BEAST) attitude = ATTITUDE
| beast = (WINGED BEAST | BIRD FLYING INSECT) attitude = FLYING ATTITUDE
| beast = SWIMMING BEAST attitude = SWIMMING ATTITUDE
)
ATTITUDE MODIFIER?
tincture or proper[tinctures]
body parts[tinctures]? {
diagnoseRuleOfTincture($tincture or proper.tincture, underLayerTinctureType);
String beastName = checkForPlurals($beast.text, number);
AdvancedCharge charge = AdvancedCharge.build(beastName, $attitude.text, $ATTITUDE MODIFIER.text,
$tincture or proper.tincture, $body parts.bodyParts);
$charges = new ArrayList<AdvancedCharge>();
for (int i = 0; i < number; i++) {
$charges.add(charge);
}
};
body parts[Tinctures tinctures] returns [Map<String, Tincture> bodyParts] :
{
bodyParts = new HashMap<String, Tincture>();
}
(
bp1 = BODY PART t1=tincture[tinctures] {
bodyParts.put($bp1.text, $t1.tincture);
}
|
(
bp2 = BODY PART t2=tincture[tinctures] {
bodyParts.put($bp2.text, $t2.tincture);
}
)*
AND bp3 = BODY PART t3=tincture[tinctures] {
bodyParts.put($bp3.text, $t3.tincture);
}
);
div returns [ShieldDivisionType division] :
{
String text = ””;
}
(
(
TIERCED {
text = $TIERCED.text + ” ”;
}
)?
PARTYPER
divType = ( ORDINARY DIV | SUBORDINARY DIV )
{
text += $divType.text;
}
(
divModifier1 = MODIFIER {
text += ” ” + $divModifier1.text;
68 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
}
)?
|
VARIABLE DIV {
text = $VARIABLE DIV.text;
}
(
divModifier2 = MODIFIER {
text += ” ” + $divModifier2.text;
}
)?
(
OF {
text += ” ” + $OF.text;
}
number digits or words {
int gyronnyOf = convertNumber($number digits or words.text);
if (gyronnyOf \% 2 != 0) {
gyronnyOf++;
diags.add(ShieldDiagnostic.build(LogLevel.WARNING, ”Parsing rule ’div’.”
+ ” ’” + $VARIABLE DIV.text + ”’ can only be of an even number;”
+ ” incremented number of sections to ” + gyronnyOf));
}
text += ” ” + gyronnyOf;
}
)?
|
CONTINUOUS DIV {
text = $CONTINUOUS DIV.text;
}
|
QUARTER {
text = $QUARTER.text;
}
)
{
if (state.errorRecovery) {
throw new RecognitionException(this.input);
}
ShieldDivision divisions = new ShieldDivision();
$division = divisions.getDivisionType(text, diags);
};
some tinctures[Tinctures tinctures, ShieldDivisionType division] returns [Field layer] :
{
int count = 0;
}
(
tincture or fur[tinctures] {
count++;
}
)+
AND
tincture or fur[tinctures] {
count++;
int numberOfTinctures = division.getNumberOfTinctures();
if (numberOfTinctures != count) {
69 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
diags.add(ShieldDiagnostic.build(LogLevel.ERROR, ”Incorrect number of tinctures specified.”
+ ” The ’” + division + ”’ division type only allows the following number of tinctures: ”
+ numberOfTinctures + ” but found ” + count));
throw new RecognitionException(this.input);
}
$layer = FieldImpl.buildDividedShieldLayer(tinctures, division);
};
tincture[Tinctures tinctures] returns [Tincture tincture] :
{
String tinctureName = ””;
}
(
COLOUR {
tinctureName = $COLOUR.text;
}
|
METAL {
tinctureName = $METAL.text;
}
)
{
try {
$tincture = tinctures.getTincture(tinctureName);
$tinctures.addTincture($tincture);
} catch (UnknownTinctureException e) {
diags.add(ShieldDiagnostic.build(LogLevel.ERROR, ”Unknown tincture found. Caught: ” + e));
throw new RecognitionException(this.input);
}
};
tincture or fur[Tinctures tinctures] returns [Tincture tincture] :
{
String tinctureName = ””;
}
(
COLOUR {
tinctureName = $COLOUR.text;
}
|
METAL {
tinctureName = $METAL.text;
}
|
FUR {
tinctureName = $FUR.text;
}
)
{
try {
$tincture = tinctures.getTincture(tinctureName);
$tinctures.addTincture($tincture);
} catch (UnknownTinctureException e) {
diags.add(ShieldDiagnostic.build(LogLevel.ERROR, ”Unknown tincture found. Caught: ” + e));
throw new RecognitionException(this.input);
}
};
70 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
tincture or proper[Tinctures tinctures] returns [Tincture tincture] :
{
String tinctureName = ””;
}
(
COLOUR {
tinctureName = $COLOUR.text;
}
|
METAL {
tinctureName = $METAL.text;
}
|
PROPER {
tinctureName = $PROPER.text;
}
)
{
try {
$tincture = tinctures.getTincture(tinctureName);
$tinctures.addTincture($tincture);
} catch (UnknownTinctureException e) {
diags.add(ShieldDiagnostic.build(LogLevel.ERROR, ”Unknown tincture found. Caught: ” + e));
throw new RecognitionException(this.input);
}
};
number digits or words :
DIGITS | NUMWORDS ( AND? NUMWORDS )* | DETERMINER ;
MODIFIER :
’reversed’ | ’sinister’ ;
TIERCED :
’tierced’ ;
ORDINARY DIV :
’fess’ | ’pale’ | ’bend’ | ’cross’ | ’saltire’ | ’chevron’ ;
SUBORDINARY DIV :
’pall’ ;
OTHER ORDINARY :
’chief’ | ’base’ ;
SUBORDINARY :
’pile’ | ’quarter’ | ’canton’ | ’flaunches’ | ’bordure’ | ’orle’ | ’tressure’ | ’gyron’ | ’fret’ ;
VARIABLE DIV :
’gyronny’ | ’barry’ | ’paly’ | ’bendy’ | ’chevronny’ ;
SUBORDINARY MULTIPLE :
( ’bar’ | ’bendlet’ | ’pallet’ | ’chevronel’ ) ’s’? ;
MOBILE CHARGE :
( ’in’? ’escutcheon’ | ’billet’ | ’lozenge’ | ’mascle’ | ’fusil’
71 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
| ’rustre’ | ’roundel’ | ’annulet’ | ’mullet’ | ’star’ ) ’s’? ;
BEAST :
( ’lion’ | ’bear’ | ’wolf’ | ’stag’ | ’leopard’ | ’horse’ | ’unicorn’ ) ’s’? ;
BIRD FLYING INSECT :
( ’owl’ | ’peacock’ | ’bee’ ) ’s’? ;
WINGED BEAST :
( ’griffin’ | ’dragon’ ) ’s’? ;
SWIMMING BEAST :
( ’fish’ | ’dolphin’ ) ’s’? ;
ATTITUDE :
’rampant’ | ’sejant’ | ’passant’ | ’couchant’ | ’courant’ | ’dormant’ | ’salient’ | ’statant’ ;
FLYING ATTITUDE :
’volant’ | ’displayed’ | ’trussed’ | ’rising’ | ’vigilant’ ;
SWIMMING ATTITUDE :
’naiant’ | ’hauriant’ ;
ATTITUDE MODIFIER :
’guardant’ | ’reguardant’ | ’affronty’ ;
BODY PART :
’langued’ | ’eyed’ | ’armed’ ;
CONTINUOUS DIV :
’chequy’ | ’lozengy’ ;
QUARTER :
’quarter’ ( ’ed’ | ’ly’ ) ;
PARTYPER :
( ’part’ ( ’ed’ | ’y’ ) ’ ’ )? ’per’ ;
PROPER :
’proper’ ;
COLOUR :
’azure’ | ’gules’ | ’vert’ | ’sable’ | ’purpure’ ;
METAL :
’or’ | ’argent’ ;
FUR :
’ermine’ | ’ermines’ | ’erminois’ | ’pean’ | ’vair’ | ’counter−vair’ | ’vair−en−pale’
| ’vair−en−point’ | ’potent’ | ’counter−potent’ | ’potent−en−pale’ | ’potent−en−point’ ;
DIGITS :
(’0’..’9’)+ ;
NUMWORDS :
’one’ | ’eleven’ | ’two’ | ’twelve’ | ’three’ | ’thirteen’ | ’four’ ’teen’? | ’five’
| ’fifteen’ | ’six’ ’teen’? | ’seven’ ’teen’? | ’eight’ ’een’? | ’nine’ ’teen’? | ’twenty’
72 of 73
Translating Blazon into Coats of Arms
Luke Torjussen
| ’thirty’ | ’fourty’ | ’fifty’ | ’sixty’ | ’seventy’ | ’eighty’ | ’ninety’ | ’hundred’ ;
OF :
’of’ ;
AND :
’and’ ;
DETERMINER :
’a’ | ’an’ ;
WS :
( ’ ’ | ’\t’ )+
{
$channel = HIDDEN;
};
73 of 73