diff --git a/.classpath b/.classpath index edb8ddf..cd780e3 100644 --- a/.classpath +++ b/.classpath @@ -5,6 +5,7 @@ + diff --git a/resources/resources/esvg/fonts/FreeMono.svg b/resources/resources/esvg/fonts/FreeMono.svg new file mode 100644 index 0000000..88c79e9 --- /dev/null +++ b/resources/resources/esvg/fonts/FreeMono.svg @@ -0,0 +1,9874 @@ + + + + +Created by FontForge 20191125 at Wed Sep 15 23:00:57 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources/esvg/fonts/FreeMonoBold.svg b/resources/resources/esvg/fonts/FreeMonoBold.svg new file mode 100644 index 0000000..e8009c3 --- /dev/null +++ b/resources/resources/esvg/fonts/FreeMonoBold.svg @@ -0,0 +1,5443 @@ + + + + +Created by FontForge 20191125 at Wed Sep 15 22:59:39 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources/esvg/fonts/FreeMonoBoldOblique.svg b/resources/resources/esvg/fonts/FreeMonoBoldOblique.svg new file mode 100644 index 0000000..e1dd340 --- /dev/null +++ b/resources/resources/esvg/fonts/FreeMonoBoldOblique.svg @@ -0,0 +1,5198 @@ + + + + +Created by FontForge 20200511 at Wed Sep 15 23:00:06 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources/esvg/fonts/FreeMonoOblique.svg b/resources/resources/esvg/fonts/FreeMonoOblique.svg new file mode 100644 index 0000000..ba8f4bc --- /dev/null +++ b/resources/resources/esvg/fonts/FreeMonoOblique.svg @@ -0,0 +1,6389 @@ + + + + +Created by FontForge 20191125 at Wed Sep 15 23:00:34 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources/esvg/fonts/FreeSans.svg b/resources/resources/esvg/fonts/FreeSans.svg new file mode 100644 index 0000000..efdc01e --- /dev/null +++ b/resources/resources/esvg/fonts/FreeSans.svg @@ -0,0 +1,15542 @@ + + + + +Created by FontForge 20200511 at Sun Sep 19 11:36:01 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources/esvg/fonts/FreeSansBold.svg b/resources/resources/esvg/fonts/FreeSansBold.svg new file mode 100644 index 0000000..d16c8bd --- /dev/null +++ b/resources/resources/esvg/fonts/FreeSansBold.svg @@ -0,0 +1,8052 @@ + + + + +Created by FontForge 20191125 at Sun Sep 19 11:41:50 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources/esvg/fonts/FreeSansBoldOblique.svg b/resources/resources/esvg/fonts/FreeSansBoldOblique.svg new file mode 100644 index 0000000..842491c --- /dev/null +++ b/resources/resources/esvg/fonts/FreeSansBoldOblique.svg @@ -0,0 +1,7236 @@ + + + + +Created by FontForge 20191125 at Sun Sep 19 11:42:50 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources/esvg/fonts/FreeSansOblique.svg b/resources/resources/esvg/fonts/FreeSansOblique.svg new file mode 100644 index 0000000..8b8c84d --- /dev/null +++ b/resources/resources/esvg/fonts/FreeSansOblique.svg @@ -0,0 +1,9376 @@ + + + + +Created by FontForge 20200511 at Sun Sep 19 11:41:10 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/resources/esvg/fonts/FreeSherif.svg b/resources/resources/esvg/fonts/FreeSherif.svg new file mode 100644 index 0000000..9f717de --- /dev/null +++ b/resources/resources/esvg/fonts/FreeSherif.svg @@ -0,0 +1,34749 @@ + + + + +Created by FontForge 20200511 at Sun Sep 19 12:35:57 2010 + By convertio +Copyleft 2002, 2003, 2005, 2008, 2009, 2010 Free Software Foundation. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/module-info.java b/src/module-info.java index 0a072de..37964fd 100644 --- a/src/module-info.java +++ b/src/module-info.java @@ -4,6 +4,7 @@ open module org.atriasoft.esvg { exports org.atriasoft.esvg; + exports org.atriasoft.esvg.font; exports org.atriasoft.esvg.render; requires transitive io.scenarium.logger; diff --git a/src/org/atriasoft/esvg/Esvg.java b/src/org/atriasoft/esvg/Esvg.java new file mode 100644 index 0000000..29be7af --- /dev/null +++ b/src/org/atriasoft/esvg/Esvg.java @@ -0,0 +1,11 @@ +package org.atriasoft.esvg; + +import org.atriasoft.etk.Uri; + +public class Esvg { + public static void init() { + Uri.addLibrary("esvg", Esvg.class, "/resources/esvg/"); + } + + private Esvg() {} +} diff --git a/src/org/atriasoft/esvg/EsvgDocument.java b/src/org/atriasoft/esvg/EsvgDocument.java index bd6a7f9..3ea8748 100644 --- a/src/org/atriasoft/esvg/EsvgDocument.java +++ b/src/org/atriasoft/esvg/EsvgDocument.java @@ -368,6 +368,32 @@ public class EsvgDocument extends Base { return true; } + /* + public float[][] renderImageFloat(final Vector2i size) { + return renderImageFloat(size, false); + } + + public float[][] renderImageFloat(Vector2i size, final boolean visualDebug) { + if (size == null) { + size = new Vector2i((int) this.size.x(), (int) this.size.y()); + } else { + if (size.x() <= 0) { + size = size.withX((int) this.size.x()); + } + if (size.y() <= 0) { + size = size.withY((int) this.size.y()); + } + } + Log.debug("Generate size " + size); + Renderer renderedElement = new Renderer(size, this, visualDebug); + // create the first element matrix modification ... + Matrix2x3f basicTrans = Matrix2x3f.IDENTITY.multiply(Matrix2x3f.createScale(new Vector2f(size.x() / this.size.x(), size.y() / this.size.y()))); + draw(renderedElement, basicTrans); + + // direct return the generated data ... + return renderedElement.getData(); + } + */ /** * Generate Image in a specific format. * @param size Size expected of the rendered image (value <=0 if it need to be automatic.) return the size generate diff --git a/src/org/atriasoft/esvg/EsvgFont.java b/src/org/atriasoft/esvg/EsvgFont.java new file mode 100644 index 0000000..cc07f39 --- /dev/null +++ b/src/org/atriasoft/esvg/EsvgFont.java @@ -0,0 +1,280 @@ +package org.atriasoft.esvg; + +import java.util.HashMap; +import java.util.Map; +import java.util.List; +import java.util.ArrayList; + +import org.atriasoft.esvg.font.Glyph; +import org.atriasoft.esvg.font.Kerning; +import org.atriasoft.esvg.internal.Log; +import org.atriasoft.esvg.render.PathModel; +import org.atriasoft.esvg.render.RenderingConfig; +import org.atriasoft.esvg.render.Weight; +import org.atriasoft.etk.Uri; +import org.atriasoft.etk.math.Matrix2x3f; +import org.atriasoft.etk.math.Vector2f; +import org.atriasoft.etk.math.Vector2i; +import org.atriasoft.etk.util.Pair; +import org.atriasoft.exml.Exml; +import org.atriasoft.exml.exception.ExmlBuilderException; +import org.atriasoft.exml.model.XmlElement; +import org.atriasoft.exml.model.XmlNode; + +// https://www.w3.org/TR/SVGTiny12/fonts.html + +public class EsvgFont { + + /** + * Load the file that might contain the svg + * @param uri File of the svg + * @return false : An error occured + * @return true : Parsing is OK + */ + public static EsvgFont load(final Uri uri) { + EsvgFont font = new EsvgFont(); + XmlNode doc = null; + try { + doc = Exml.parse(uri); + } catch (ExmlBuilderException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + if (!(doc instanceof XmlElement root)) { + Log.error("can not load the SVG font ==> wrong root node"); + return null; + } + if (!root.existNode("svg") || !(root.getNodeNoExcept("svg") instanceof XmlElement svgNode)) { + Log.error("can not load Node in svg document"); + return null; + } + if (!svgNode.existNode("defs") || !(svgNode.getNodeNoExcept("defs") instanceof XmlElement defsNode)) { + Log.error("can not load Node in svg document"); + return null; + } + if (!defsNode.existNode("font") || !(defsNode.getNodeNoExcept("font") instanceof XmlElement fontElement)) { + Log.error("can not load Node in svg document"); + return null; + } + int nbGlyph = 0; + for (XmlNode values : fontElement.getNodes()) { + if (values.getValue().equals("glyph")) { + nbGlyph++; + Log.info("find flyph: " + nbGlyph); + Glyph tmp = Glyph.valueOf(values.toElement()); + if (tmp != null) { + font.glyphs.put(tmp.getUnicodeValue(), tmp); + } + } else if (values.getValue().equals("hkern")) { + // check later ... + } else if (values.getValue().equals("missing-glyph")) { + font.missingGlyph = Glyph.valueOf(values.toElement()); + } else if (values.getValue().equals("font-face")) { + if (values instanceof XmlElement fontFace) { + font.fontFamily = fontFace.getAttribute("font-family", "unknown"); + font.fontStretch = fontFace.getAttribute("font-stretch", "normal"); + font.fontWeight = Integer.parseInt(fontFace.getAttribute("font-weight", "400")); + font.unitsPerEm = Integer.parseInt(fontFace.getAttribute("units-per-em", "1000")); + font.ascent = Integer.parseInt(fontFace.getAttribute("ascent", "800")); + font.descent = Integer.parseInt(fontFace.getAttribute("descent", "-200")); + font.xHeight = Integer.parseInt(fontFace.getAttribute("x-height", "450")); + font.capHeight = Integer.parseInt(fontFace.getAttribute("cap-height", "662")); + font.underlineThickness = Integer.parseInt(fontFace.getAttribute("underline-thickness", "50")); + font.underlinePosition = Integer.parseInt(fontFace.getAttribute("underline-position", "-150")); + //panose-1="2 2 6 3 5 4 5 2 3 4" + String tmp = fontFace.getAttribute("panose-1", null); + String[] tmpSplit = tmp.split(" "); + font.panose1 = new int[tmpSplit.length]; + for (int iii = 0; iii < tmpSplit.length; iii++) { + font.panose1[iii] = Integer.parseInt(tmpSplit[iii]); + } + //bbox="-879 -545 1767 934" + tmp = fontFace.getAttribute("bbox", null); + tmpSplit = tmp.split(" "); + font.bbox = new int[tmpSplit.length]; + for (int iii = 0; iii < tmpSplit.length; iii++) { + font.bbox[iii] = Integer.parseInt(tmpSplit[iii]); + } + //unicode-range="U+0020-1F093" + tmp = fontFace.getAttribute("unicode-range", null); + tmpSplit = tmp.split("-"); + int start = Integer.parseInt(tmpSplit[0].substring(2), 16); + int stop = Integer.parseInt(tmpSplit[1], 16); + font.unicodeRange = new Pair<>(start, stop); + } + } else { + Log.warning("unsupported node name :" + values.getValue()); + } + } + for (XmlNode values : fontElement.getNodes()) { + if (values.getValue().equals("hkern")) { + if (values instanceof XmlElement kernElem) { + String g1 = kernElem.getAttribute("g1", null); + String g2 = kernElem.getAttribute("g2", null); + if (g1 == null || g2 == null) { + continue; + } + float offset = Float.parseFloat(kernElem.getAttribute("k", "0")); + if (offset == 0.0f) { + continue; + } + String[] g1Splited = g1.split(","); + String[] g2Splited = g2.split(","); + // create the list of kerning of the next elements + List elementsKerning = new ArrayList<>(); + for (int iii = 0; iii < g2Splited.length; iii++) { + for (Map.Entry entry : font.glyphs.entrySet()) { + if (entry.getValue().getName().equals(g2Splited[iii])) { + elementsKerning.add(new Kerning(offset, entry.getKey())); + break; + } + } + } + // add it on the + for (int iii = 0; iii < g1Splited.length; iii++) { + for (Map.Entry entry : font.glyphs.entrySet()) { + if (entry.getValue().getName().equals(g1Splited[iii])) { + entry.getValue().addKerning(elementsKerning); + break; + } + } + } + } + } + } + return font; + } + + // The maximum accented height of the font within the font coordinate system. + private int ascent = 800; // this is the height of the font (on top...) + private int[] bbox = { -879, -545, 1767, 934 }; + // The height of uppercase glyphs in the font within the font coordinate system. + private int capHeight = 662; + // The maximum unaccented depth of the font within the font coordinate system. + private int descent = -200; // lower size of the font + private String fontFamily = "unknown"; + private String fontStretch = "normal"; + private int fontWeight = 400; + private final Map glyphs = new HashMap<>(); + // The horizontal advance after rendering the glyph in horizontal orientation. If the attribute is not specified, the effect is as if the attribute were set to the value of the font's 'horiz-adv-x' attribute. + // Glyph widths are required to be non-negative, even if the glyph is typically rendered right-to-left, as in Hebrew and Arabic scripts. + private final int horizAdvX = 0; + private Glyph missingGlyph = null; + private int[] panose1 = { 2, 2, 6, 3, 5, 4, 5, 2, 3, 4 }; + private int underlinePosition = -150; + private int underlineThickness = 50; + private Pair unicodeRange = new Pair<>(0x0020, 0x1F093); + private int unitsPerEm = 1000; // full size of the font + // The height of lowercase glyphs in the font within the font coordinate system. + private int xHeight = 450; + + /** + * Get the font real size use (height) for all the characters. + * @param fontSize size of the font the user require + * @return Real size in pixel of element can impact the output + */ + public int calculateFontRealHeight(final int fontSize) { + return fontSize * this.unitsPerEm / this.capHeight; + + } + + public int calculateWidth(final String uVal, final int fontSize) { + return calculateWidth(uVal, fontSize, true); + } + + public int calculateWidth(final String data, final int fontSize, final boolean withKerning) { + int realSize = calculateFontRealHeight(fontSize); + float scale = (float) realSize / (float) this.unitsPerEm; + int out = 0; + int lastValue = 0; + for (char uVal : data.toCharArray()) { + Glyph glyph = getGlyph(uVal); + if (glyph == null) { + lastValue = uVal; + continue; + } + if (withKerning) { + out -= glyph.getKerning(lastValue) * scale; + lastValue = uVal; + } + out += glyph.getHorizAdvX() * scale; + } + return out; + } + + public Glyph getGlyph(final int glyphIndex) { + Glyph out = this.glyphs.get(glyphIndex); + if (out == null) { + return this.missingGlyph; + } + return out; + } + + public int getNumGlyphs() { + return this.glyphs.size(); + } + + public boolean hasKerning() { + // TODO Auto-generated method stub + return false; + } + + public Weight render(final int uVal, final int fontSize) { + int realSize = calculateFontRealHeight(fontSize); + Glyph glyph = getGlyph(uVal); + if (glyph == null) { + return null; + } + float scale = (float) realSize / (float) this.unitsPerEm; + RenderingConfig config = new RenderingConfig(10, 0.25f, 8); + Matrix2x3f transform = Matrix2x3f.createTranslate(new Vector2f(0, -this.descent)).multiply(Matrix2x3f.createScale(scale)); + PathModel model = glyph.getModel(); + if (model == null) { + return null; + } + Weight data = glyph.getModel().drawFill(new Vector2i((int) (glyph.getHorizAdvX() * scale), realSize), transform, 8, config); + return data; + } + + public Weight render(final String uVal, final int fontSize) { + return render(uVal, fontSize, true); + } + + public Weight render(final String data, final int fontSize, final boolean withKerning) { + int widthOut = calculateWidth(data, fontSize, withKerning); + + int realSize = calculateFontRealHeight(fontSize); + float scale = (float) realSize / (float) this.unitsPerEm; + + Weight weight = new Weight(new Vector2i(widthOut, realSize)); + + int offsetWriting = 0; + int lastValue = 0; + for (char uVal : data.toCharArray()) { + Glyph glyph = getGlyph(uVal); + if (glyph == null) { + lastValue = uVal; + continue; + } + if (withKerning) { + offsetWriting -= glyph.getKerning(lastValue) * scale; + Log.info(" ==> kerning offset = " + (glyph.getKerning(lastValue) * scale)); + lastValue = uVal; + } + + float advenceXLocal = glyph.getHorizAdvX() * scale; + + RenderingConfig config = new RenderingConfig(10, 0.25f, 8); + Matrix2x3f transform = Matrix2x3f.createTranslate(new Vector2f(0, -this.descent)).multiply(Matrix2x3f.createScale(scale)); + PathModel model = glyph.getModel(); + if (model != null) { + Weight redered = model.drawFill(new Vector2i((int) (glyph.getHorizAdvX() * scale), realSize), transform, 8, config); + weight.fusion(redered, offsetWriting, 0); + } + offsetWriting += advenceXLocal; + + } + return weight; + } +} diff --git a/src/org/atriasoft/esvg/Path.java b/src/org/atriasoft/esvg/Path.java index c54e817..f41bafb 100644 --- a/src/org/atriasoft/esvg/Path.java +++ b/src/org/atriasoft/esvg/Path.java @@ -12,7 +12,6 @@ import org.atriasoft.esvg.render.DynamicColor; import org.atriasoft.esvg.render.SegmentList; import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; -import org.atriasoft.etk.math.Vector2i; import org.atriasoft.etk.util.Dynamic; import org.atriasoft.exml.model.XmlElement; import org.atriasoft.exml.parser.Tools; @@ -39,21 +38,200 @@ public class Path extends Base { } - private static String cleanBadSpaces(final String input) { - StringBuilder out = new StringBuilder(input.length()); - boolean haveSpace = false; - for (char it : input.toCharArray()) { - if (it == ' ' || it == '\t' || it == '\r') { - haveSpace = true; - } else { - if (haveSpace) { - haveSpace = false; - out.append(' '); - } - out.append(it); + public static PathModel createPathModel(final String d) { + PathModel out = new PathModel(); + Log.verbose("Parse Path : \"" + d + "\""); + List commandsSplited = Path.splitCommand(d); + String[] listDot = null; + + // TODO REWORK this, can be done with a simple split and search in a list... + for (Command sss = Path.extractCmd(commandsSplited, 0); sss != null; sss = Path.extractCmd(commandsSplited, sss.offset())) { + boolean relative = false; + listDot = sss.listElem(); + + // Log.verbose("Find new command : '" + sss.cmd + "'"); + // if (listDot != null) { + // for (int jjj = 0; jjj < listDot.length; jjj++) { + // Log.verbose(" -> '" + listDot[jjj] + "'"); + // } + // } else { + // Log.verbose(" -> no elements"); + // } + switch (sss.cmd) { + case 'm': // Move to (relative) + relative = true; + case 'M': // Move to (absolute) + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + if (listDot.length % 2 != 0) { + Log.warning("the PATH command " + sss.cmd + " must be a multiple of 2"); + break; + } + // 2 Elements ... + if (listDot.length >= 2) { + out.moveTo(relative, new Vector2f(Float.parseFloat(listDot[0]), Float.parseFloat(listDot[1]))); + } + for (int iii = 2; iii < listDot.length; iii += 2) { + out.lineTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); + } + break; + case 'l': // Line to (relative) + relative = true; + case 'L': // Line to (absolute) + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + if (listDot.length % 2 != 0) { + Log.warning("the PATH command " + sss.cmd + " must be a multiple of 2"); + break; + } + for (int iii = 0; iii < listDot.length; iii += 2) { + out.lineTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); + } + break; + + case 'v': // Vertical Line to (relative) + relative = true; + case 'V': // Vertical Line to (absolute) + // 1 Element ... + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + for (int iii = 0; iii < listDot.length; iii++) { + out.lineToV(relative, Float.parseFloat(listDot[iii])); + } + break; + + case 'h': // Horizantal Line to (relative) + relative = true; + case 'H': // Horizantal Line to (absolute) + // 1 Element ... + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + for (int iii = 0; iii < listDot.length; iii++) { + out.lineToH(relative, Float.parseFloat(listDot[iii])); + } + break; + + case 'q': // Quadratic Bezier curve (relative) + relative = true; + case 'Q': // Quadratic Bezier curve (absolute) + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + // 4 Elements ... + if (listDot.length % 4 != 0) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length + " (must have 4 numbers)"); + break; + } + for (int iii = 0; iii < listDot.length; iii += 4) { + out.bezierCurveTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), + new Vector2f(Float.parseFloat(listDot[iii + 2]), Float.parseFloat(listDot[iii + 3]))); + } + break; + + case 't': // smooth quadratic Bezier curve to (relative) + relative = true; + case 'T': // smooth quadratic Bezier curve to (absolute) + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + // 4 Elements ... + if (listDot.length % 2 != 0) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length + " (must have 2 numbers)"); + break; + } + // 2 Elements ... + for (int iii = 0; iii < listDot.length; iii += 2) { + out.bezierSmoothCurveTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1]))); + } + break; + + case 'c': // curve to (relative) + relative = true; + case 'C': // curve to (absolute) + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + // 6 Elements ... + if (listDot.length % 6 != 0) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length + "(Must be a multiple of 6)"); + break; + } + for (int iii = 0; iii < listDot.length; iii += 6) { + out.curveTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), + new Vector2f(Float.parseFloat(listDot[iii + 2]), Float.parseFloat(listDot[iii + 3])), + new Vector2f(Float.parseFloat(listDot[iii + 4]), Float.parseFloat(listDot[iii + 5]))); + } + break; + + case 's': // smooth curve to (relative) + relative = true; + case 'S': // smooth curve to (absolute) + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + // 4 Elements ... + if (listDot.length % 4 != 0) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length + "(Must be a multiple of 4)"); + break; + } + for (int iii = 0; iii < listDot.length; iii += 4) { + out.smoothCurveTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), + new Vector2f(Float.parseFloat(listDot[iii + 2]), Float.parseFloat(listDot[iii + 3]))); + } + break; + + case 'a': // elliptical Arc (relative) + relative = true; + case 'A': // elliptical Arc (absolute) + if (listDot == null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); + break; + } + // 4 element ff,ff f i,i ff,ff Elements ... + if (listDot.length % 7 != 0) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); + break; + } + for (int iii = 0; iii < listDot.length; iii += 7) { + boolean largeArcFlag = true; + boolean sweepFlag = true; + if (Integer.parseInt(listDot[iii + 3]) == 0) { + largeArcFlag = false; + } + if (Integer.parseInt(listDot[iii + 4]) == 0) { + sweepFlag = false; + } + out.ellipticTo(relative, new Vector2f(Float.parseFloat(listDot[iii]), Float.parseFloat(listDot[iii + 1])), Float.parseFloat(listDot[iii + 2]), largeArcFlag, sweepFlag, + new Vector2f(Float.parseFloat(listDot[iii + 5]), Float.parseFloat(listDot[iii + 6]))); + } + break; + case 'z': // closepath (relative) + relative = true; + case 'Z': // closepath (absolute) + // 0 Element ... + if (listDot != null) { + Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); + break; + } + out.close(relative); + break; + default: + Log.error("Unknow error : '" + sss.cmd + "'"); } } - return out.toString(); + return out; } //return the next char position ... (after 'X' or NULL) @@ -67,12 +245,12 @@ public class Path extends Base { // Log.warning(" -[" + iii + "] '" + input.get(iii) + "'"); // } if (input.get(offset).length() != 1) { - Log.error("Error in the SVG Path : '" + input.get(offset) + "' [" + offset); + Log.error("Error in the SVG Path : '" + input.get(offset) + "' [" + Integer.toString(offset)); return null; } char cmd = input.get(offset).charAt(0); if (!((cmd <= 'Z' && cmd >= 'A') || (cmd <= 'z' && cmd >= 'a'))) { - Log.error("Error in the SVG Path : '" + cmd + "' [" + offset); + Log.error("Error in the SVG Path : '" + cmd + "' [" + Integer.toString(offset)); return null; } //Log.verbose("Find command : " + cmd); @@ -89,7 +267,7 @@ public class Path extends Base { } int length = iii - (offset + 1); if (length == 0) { - return new Command(cmd, null, iii + 1); + return new Command(cmd, null, iii); } String[] outputList = new String[length]; for (int jjj = 0; jjj < length; jjj++) { @@ -98,6 +276,40 @@ public class Path extends Base { return new Command(cmd, outputList, iii); } + static List splitCommand(final String data) { + List out = new ArrayList<>(); + StringBuilder tmpString = new StringBuilder(20); + boolean isNumber = false; + for (char it : data.toCharArray()) { + // ',' is here beause some people oprefer the ' ' instead of ',' + if (it == ' ' || it == '\t' || it == '\r' || it == '\n' || it == ',') { + String elements = tmpString.toString(); + if (!elements.isEmpty()) { + out.add(elements); + } + tmpString.setLength(0); + isNumber = false; + } else if (Tools.checkNumber(it, true) || it == '.') { + isNumber = true; + tmpString.append(it); + } else if ((it <= 'Z' && it >= 'A') || (it <= 'z' && it >= 'a')) { + if (isNumber) { + out.add(tmpString.toString()); + tmpString.setLength(0); + } + isNumber = false; + out.add(Character.toString(it)); + } else { + Log.error("Can not parse path : '" + it + "'"); + } + } + String elements = tmpString.toString(); + if (!elements.isEmpty()) { + out.add(elements); + } + return out; + } + public PathModel listElement = new PathModel(); public Path(final PaintState parentPaintState) { @@ -186,219 +398,8 @@ public class Path extends Base { Log.warning("path: missing 'd' attribute or empty"); return false; } - Log.verbose("Parse Path : \"" + elementXML1 + "\""); - List commandsSplited = splitCommand(elementXML1); - String[] listDot = null; - - // TODO REWORK this, can be done with a simple split and search in a list... - for (Command sss = Path.extractCmd(commandsSplited, 0); sss != null; sss = Path.extractCmd(commandsSplited, sss.offset())) { - boolean relative = false; - listDot = sss.listElem(); - - Log.error("Find new command : '" + sss.cmd + "'"); - if (listDot != null) { - for (int jjj = 0; jjj < listDot.length; jjj++) { - Log.error(" -> '" + listDot[jjj] + "'"); - } - } else { - Log.error(" -> no elements"); - } - switch (sss.cmd) { - case 'm': // Move to (relative) - relative = true; - case 'M': // Move to (absolute) - if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); - break; - } - // 2 Elements ... - if (listDot.length >= 1) { - this.listElement.moveTo(relative, Vector2f.valueOf(listDot[0])); - } - for (int iii = 1; iii < listDot.length; iii++) { - this.listElement.lineTo(relative, Vector2f.valueOf(listDot[iii])); - } - break; - case 'l': // Line to (relative) - relative = true; - case 'L': // Line to (absolute) - if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); - break; - } - for (int iii = 0; iii < listDot.length; iii++) { - this.listElement.lineTo(relative, Vector2f.valueOf(listDot[iii])); - } - break; - - case 'v': // Vertical Line to (relative) - relative = true; - case 'V': // Vertical Line to (absolute) - // 1 Element ... - if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); - break; - } - for (int iii = 0; iii < listDot.length; iii++) { - this.listElement.lineToV(relative, Float.parseFloat(listDot[iii])); - } - break; - - case 'h': // Horizantal Line to (relative) - relative = true; - case 'H': // Horizantal Line to (absolute) - // 1 Element ... - if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); - break; - } - for (int iii = 0; iii < listDot.length; iii++) { - this.listElement.lineToH(relative, Float.parseFloat(listDot[iii])); - } - break; - - case 'q': // Quadratic Bezier curve (relative) - relative = true; - case 'Q': // Quadratic Bezier curve (absolute) - if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); - break; - } - // 4 Elements ... - if (listDot.length % 2 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); - break; - } - for (int iii = 0; iii < listDot.length; iii += 2) { - this.listElement.bezierCurveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1])); - } - break; - - case 't': // smooth quadratic Bezier curve to (relative) - relative = true; - case 'T': // smooth quadratic Bezier curve to (absolute) - // 2 Elements ... - for (int iii = 0; iii < listDot.length; iii++) { - this.listElement.bezierSmoothCurveTo(relative, Vector2f.valueOf(listDot[iii])); - } - break; - - case 'c': // curve to (relative) - relative = true; - case 'C': // curve to (absolute) - if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); - break; - } - // 6 Elements ... - if (listDot.length % 3 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); - break; - } - for (int iii = 0; iii < listDot.length; iii += 3) { - this.listElement.curveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1]), Vector2f.valueOf(listDot[iii + 2])); - } - break; - - case 's': // smooth curve to (relative) - relative = true; - case 'S': // smooth curve to (absolute) - if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); - break; - } - // 4 Elements ... - if (listDot.length % 2 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); - break; - } - for (int iii = 0; iii < listDot.length; iii += 2) { - this.listElement.smoothCurveTo(relative, Vector2f.valueOf(listDot[iii]), Vector2f.valueOf(listDot[iii + 1])); - } - break; - - case 'a': // elliptical Arc (relative) - relative = true; - case 'A': // elliptical Arc (absolute) - if (listDot == null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot); - break; - } - // 4 element ff,ff f i,i ff,ff Elements ... - if (listDot.length % 4 != 0) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); - break; - } - for (int iii = 0; iii < listDot.length; iii += 7) { - boolean largeArcFlag = true; - boolean sweepFlag = true; - Vector2i tmp = Vector2i.valueOf(listDot[iii + 2]); - if (tmp.x() == 0) { - largeArcFlag = false; - } - if (tmp.y() == 0) { - sweepFlag = false; - } - this.listElement.ellipticTo(relative, Vector2f.valueOf(listDot[iii]), Float.parseFloat(listDot[iii + 1]), largeArcFlag, sweepFlag, Vector2f.valueOf(listDot[iii + 3])); - } - break; - case 'z': // closepath (relative) - relative = true; - case 'Z': // closepath (absolute) - // 0 Element ... - if (listDot != null) { - Log.warning("the PATH command " + sss.cmd + " has not the good number of element = " + listDot.length); - break; - } - this.listElement.close(relative); - break; - default: - Log.error("Unknow error : '" + sss.cmd + "'"); - } - } - - return true; - } - - List splitCommand(final String data) { - List out = new ArrayList<>(); - StringBuilder tmpString = new StringBuilder(20); - boolean isText = false; - boolean isNumber = false; - for (char it : data.toCharArray()) { - if (it == ' ' || it == '\t' || it == '\r') { - String elements = tmpString.toString(); - if (!elements.isEmpty()) { - out.add(elements); - } - tmpString.setLength(0); - isText = false; - isNumber = false; - } else if (Tools.checkNumber(it, true) || it == ',' || it == '.') { - if (isText) { - out.add(tmpString.toString()); - tmpString.setLength(0); - } - isText = false; - isNumber = true; - tmpString.append(it); - } else if ((it <= 'Z' && it >= 'A') || (it <= 'z' && it >= 'a')) { - if (isNumber) { - out.add(tmpString.toString()); - tmpString.setLength(0); - } - isText = true; - isNumber = false; - tmpString.append(it); - } else { - Log.error("Can not parse path : '" + it + "'"); - } - } - String elements = tmpString.toString(); - if (!elements.isEmpty()) { - out.add(elements); - } - return out; + this.listElement = Path.createPathModel(elementXML1); + return this.listElement != null; } } diff --git a/src/org/atriasoft/esvg/Renderer.java b/src/org/atriasoft/esvg/Renderer.java index abb3341..7ecbe72 100644 --- a/src/org/atriasoft/esvg/Renderer.java +++ b/src/org/atriasoft/esvg/Renderer.java @@ -20,7 +20,6 @@ import org.atriasoft.etk.util.ArraysTools; * @copyright 2011, Edouard DUPIN, all right reserved * @license MPL v2.0 (see license file) */ - public class Renderer { private static final boolean DEBUG_MODE = false; protected Color[][] buffer; // for debug diff --git a/src/org/atriasoft/esvg/RendererFont.java b/src/org/atriasoft/esvg/RendererFont.java new file mode 100644 index 0000000..1fe45ee --- /dev/null +++ b/src/org/atriasoft/esvg/RendererFont.java @@ -0,0 +1,103 @@ +package org.atriasoft.esvg; + +import org.atriasoft.esvg.render.Weight; +import org.atriasoft.etk.Color; +import org.atriasoft.etk.math.FMath; +import org.atriasoft.etk.math.Vector2i; +import org.atriasoft.etk.util.ArraysTools; + +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +public class RendererFont { + protected float[][] buffer; // for debug + protected EsvgFont document; // for debug + + protected int interpolationRecurtionMax = 10; + + protected float interpolationThreshold = 0.25f; + protected int nbSubScanLine = 8; + protected Vector2i size; + + public RendererFont(final Vector2i size, final EsvgFont document) { + this(size, document, false); + } + + public RendererFont(final Vector2i size, final EsvgFont document, final boolean visualDebug) { + this.size = size; + this.document = document; + setSize(size); + } + + float[][] getData() { + return this.buffer; + } + + int getInterpolationRecurtionMax() { + return this.interpolationRecurtionMax; + } + + float getInterpolationThreshold() { + return this.interpolationThreshold; + } + + int getNumberSubScanLine() { + return this.nbSubScanLine; + } + + Vector2i getSize() { + return this.size; + } + + protected float mergeColor(final float base, final float integration) { + return FMath.avg(0.0f, integration + base, 1.0f); + } + + public void print(final Weight weightFill, final Weight weightStroke, final float opacity) { + // all together + for (int yyy = 0; yyy < this.size.y(); ++yyy) { + for (int xxx = 0; xxx < this.size.x(); ++xxx) { + + Vector2i pos = new Vector2i(xxx, yyy); + float valueFill = weightFill.get(pos); + float valueStroke = weightStroke.get(pos); + // calculate merge of stroke and fill value: + Color intermediateColorFill = Color.NONE; + /* + Color intermediateColorStroke = Color.NONE; + if (colorFill != null && valueFill != 0.0f) { + intermediateColorFill = colorFill.getColor(pos); + intermediateColorFill = intermediateColorFill.withA(intermediateColorFill.a() * valueFill); + } + if (colorStroke != null && valueStroke != 0.0f) { + intermediateColorStroke = colorStroke.getColor(pos); + intermediateColorStroke = intermediateColorStroke.withA(intermediateColorStroke.a() * valueStroke); + } + Color intermediateColor = mergeColor(intermediateColorFill, intermediateColorStroke); + intermediateColor = intermediateColor.withA(intermediateColor.a() * opacity); + this.buffer[yyy][xxx] = mergeColor(this.buffer[yyy][xxx], intermediateColor);*/ + } + } + } + + public void setInterpolationRecurtionMax(final int value) { + this.interpolationRecurtionMax = FMath.avg(1, value, 200); + } + + void setInterpolationThreshold(final float value) { + this.interpolationThreshold = FMath.avg(0.0f, value, 20000.0f); + } + + void setNumberSubScanLine(final int value) { + this.nbSubScanLine = FMath.avg(1, value, 200); + } + + public void setSize(final Vector2i size) { + this.size = size; + this.buffer = new float[this.size.y()][this.size.x()]; + ArraysTools.fill2(this.buffer, 0.0f); + } + +} diff --git a/src/org/atriasoft/esvg/font/Glyph.java b/src/org/atriasoft/esvg/font/Glyph.java new file mode 100644 index 0000000..14503b0 --- /dev/null +++ b/src/org/atriasoft/esvg/font/Glyph.java @@ -0,0 +1,154 @@ +package org.atriasoft.esvg.font; + +import java.util.ArrayList; +import java.util.List; + +import org.atriasoft.esvg.Path; +import org.atriasoft.esvg.internal.Log; +import org.atriasoft.esvg.render.PathModel; +import org.atriasoft.exml.model.XmlElement; + +public class Glyph { + private static final boolean LAZY_MODE = true; + + public static Glyph valueOf(final XmlElement element) { + if (element == null) { + return null; + } + String name = element.getAttribute("glyph-name", null); + Log.verbose("get glyph name = '" + name + "'"); + int horizAdvX = Integer.parseInt(element.getAttribute("horiz-adv-x", "0")); + Log.verbose(" horizAdvX= '" + horizAdvX + "'"); + String unicode = element.getAttribute("unicode", null); + Log.verbose(" unicode= '" + unicode + "'"); + if (unicode == null) { + Log.debug("Not manage glyph : '" + name + "' (missing unicode value)"); + return null; + } + String d = element.getAttribute("d", null); + Log.verbose(" d= '" + d + "'"); + int unicodeValue = 0; + if (unicode.startsWith("&#x") && unicode.endsWith(";")) { + String subElement = unicode.substring(3, unicode.length() - 1); + if (subElement.indexOf("&") != -1) { + Log.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); + return null; + } + unicodeValue = Integer.parseInt(subElement, 16); + } else if (unicode.startsWith("&#") && unicode.endsWith(";")) { + String subElement = unicode.substring(2, unicode.length() - 1); + if (subElement.indexOf("&") != -1) { + Log.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); + return null; + } + unicodeValue = Integer.parseInt(subElement, 16); + } else if (unicode.length() != 1) { + Log.debug("not supported glyph concatenarion" + name + " value='" + unicode + "'"); + return null; + } else { + unicodeValue = unicode.charAt(0); + } + Log.verbose(" unicodeValue= '" + unicodeValue + "'"); + Glyph out = new Glyph(horizAdvX, d, name, unicode, unicodeValue); + if (!Glyph.LAZY_MODE) { + // when not in lazy mode we force the parsing of the model, this permit to check the whole font... otherwise many font is really big > 8000 glyph, then it is a waste of time... + out.getModel(); + } + return out; + } + + private int horizAdvX; + private List kernings = new ArrayList<>(); + private PathModel model; + private String name; + private final String path; + private String unicode; + private int unicodeValue; + + public Glyph(final int horizAdvX, final PathModel model, final String name, final String unicode, final int unicodeValue) { + this.horizAdvX = horizAdvX; + this.model = model; + this.path = null; + this.name = name; + this.unicode = unicode; + this.unicodeValue = unicodeValue; + } + + public Glyph(final int horizAdvX, final String path, final String name, final String unicode, final int unicodeValue) { + this.horizAdvX = horizAdvX; + this.model = null; + this.path = path; + this.name = name; + this.unicode = unicode; + this.unicodeValue = unicodeValue; + } + + public void addKerning(final List elementsKerning) { + this.kernings.addAll(elementsKerning); + } + + public int getHorizAdvX() { + return this.horizAdvX; + } + + public float getKerning(final int unicodeValue) { + if (unicodeValue == 0) { + return 0.0f; + } + for (Kerning elem : this.kernings) { + if (elem.unicode() == unicodeValue) { + Log.info("Get kerning between : '" + (char) this.unicodeValue + "' and '" + (char) unicodeValue + "' => " + elem.offset()); + return elem.offset(); + } + } + return 0; + } + + public List getKernings() { + return this.kernings; + } + + public PathModel getModel() { + if (this.model == null && this.path != null) { + this.model = Path.createPathModel(this.path); + } + return this.model; + } + + public String getName() { + return this.name; + } + + public String getUnicode() { + return this.unicode; + } + + public Integer getUnicodeValue() { + return this.unicodeValue; + } + + public void setHorizAdvX(final int horizAdvX) { + this.horizAdvX = horizAdvX; + } + + public void setKernings(final List kernings) { + this.kernings = kernings; + } + + public void setModel(final PathModel model) { + this.model = model; + } + + public void setName(final String name) { + this.name = name; + } + + public void setUnicode(final String unicode) { + this.unicode = unicode; + } + + public void setUnicodeValue(final int unicodeValue) { + this.unicodeValue = unicodeValue; + } + +} diff --git a/src/org/atriasoft/esvg/font/Kerning.java b/src/org/atriasoft/esvg/font/Kerning.java new file mode 100644 index 0000000..5e45969 --- /dev/null +++ b/src/org/atriasoft/esvg/font/Kerning.java @@ -0,0 +1,5 @@ +package org.atriasoft.esvg.font; + +public record Kerning( + float offset, + int unicode) {} diff --git a/src/org/atriasoft/esvg/internal/Log.java b/src/org/atriasoft/esvg/internal/Log.java index b72bbc3..7716268 100644 --- a/src/org/atriasoft/esvg/internal/Log.java +++ b/src/org/atriasoft/esvg/internal/Log.java @@ -4,62 +4,63 @@ import io.scenarium.logger.LogLevel; import io.scenarium.logger.Logger; public class Log { - private static final String LIBNAME = "esvg"; - private static final String LIBNAMEDRAW = Logger.getDrawableName(Log.LIBNAME); - private static final boolean PRINTCRITICAL = Logger.getNeedPrint(Log.LIBNAME, LogLevel.CRITICAL); - private static final boolean PRINTDEBUG = Logger.getNeedPrint(Log.LIBNAME, LogLevel.DEBUG); - private static final boolean PRINTERROR = Logger.getNeedPrint(Log.LIBNAME, LogLevel.ERROR); - private static final boolean PRINTINFO = Logger.getNeedPrint(Log.LIBNAME, LogLevel.INFO); - private static final boolean PRINTPRINT = Logger.getNeedPrint(Log.LIBNAME, LogLevel.PRINT); - private static final boolean PRINTTODO = Logger.getNeedPrint(Log.LIBNAME, LogLevel.TODO); - private static final boolean PRINTVERBOSE = Logger.getNeedPrint(Log.LIBNAME, LogLevel.VERBOSE); - private static final boolean PRINTWARNING = Logger.getNeedPrint(Log.LIBNAME, LogLevel.WARNING); + private static final boolean FORCE_ALL = false; + private static final String LIB_NAME = "esvg"; + private static final String LIB_NAME_DRAW = Logger.getDrawableName(Log.LIB_NAME); + private static final boolean PRINT_CRITICAL = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.CRITICAL); + private static final boolean PRINT_DEBUG = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.DEBUG); + private static final boolean PRINT_ERROR = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.ERROR); + private static final boolean PRINT_INFO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.INFO); + private static final boolean PRINT_PRINT = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.PRINT); + private static final boolean PRINT_TODO = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.TODO); + private static final boolean PRINT_VERBOSE = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.VERBOSE); + private static final boolean PRINT_WARNING = Logger.getNeedPrint(Log.LIB_NAME, LogLevel.WARNING); public static void critical(final String data) { - if (Log.PRINTCRITICAL) { - Logger.critical(Log.LIBNAMEDRAW, data); + if (Log.PRINT_CRITICAL || Log.FORCE_ALL) { + Logger.critical(Log.LIB_NAME_DRAW, data); } } public static void debug(final String data) { - if (Log.PRINTDEBUG) { - Logger.debug(Log.LIBNAMEDRAW, data); + if (Log.PRINT_DEBUG || Log.FORCE_ALL) { + Logger.debug(Log.LIB_NAME_DRAW, data); } } public static void error(final String data) { - if (Log.PRINTERROR) { - Logger.error(Log.LIBNAMEDRAW, data); + if (Log.PRINT_ERROR || Log.FORCE_ALL) { + Logger.error(Log.LIB_NAME_DRAW, data); } } public static void info(final String data) { - if (Log.PRINTINFO) { - Logger.info(Log.LIBNAMEDRAW, data); + if (Log.PRINT_INFO || Log.FORCE_ALL) { + Logger.info(Log.LIB_NAME_DRAW, data); } } public static void print(final String data) { - if (Log.PRINTPRINT) { - Logger.print(Log.LIBNAMEDRAW, data); + if (Log.PRINT_PRINT || Log.FORCE_ALL) { + Logger.print(Log.LIB_NAME_DRAW, data); } } public static void todo(final String data) { - if (Log.PRINTTODO) { - Logger.todo(Log.LIBNAMEDRAW, data); + if (Log.PRINT_TODO || Log.FORCE_ALL) { + Logger.todo(Log.LIB_NAME_DRAW, data); } } public static void verbose(final String data) { - if (Log.PRINTVERBOSE) { - Logger.verbose(Log.LIBNAMEDRAW, data); + if (Log.PRINT_VERBOSE || Log.FORCE_ALL) { + Logger.verbose(Log.LIB_NAME_DRAW, data); } } public static void warning(final String data) { - if (Log.PRINTWARNING) { - Logger.warning(Log.LIBNAMEDRAW, data); + if (Log.PRINT_WARNING || Log.FORCE_ALL) { + Logger.warning(Log.LIB_NAME_DRAW, data); } } diff --git a/src/org/atriasoft/esvg/render/DynamicColorSpecial.java b/src/org/atriasoft/esvg/render/DynamicColorSpecial.java index 2683f6a..8d0feb6 100644 --- a/src/org/atriasoft/esvg/render/DynamicColorSpecial.java +++ b/src/org/atriasoft/esvg/render/DynamicColorSpecial.java @@ -257,7 +257,7 @@ public class DynamicColorSpecial implements DynamicColor { } break; case REFLECT: - ratio -= ((int) (ratio) >> 1) + 1; + ratio -= ((int) (ratio)) / 2 * 2.0f; if (ratio > 1.0f) { ratio = 2.0f - ratio; } @@ -305,7 +305,7 @@ public class DynamicColorSpecial implements DynamicColor { break; case REFLECT: ratio = FMath.abs(ratio); - ratio -= ((int) (ratio) >> 1) + 1; + ratio -= ((int) (ratio)) / 2 * 2.0f; if (ratio > 1.0f) { ratio = 2.0f - ratio; } @@ -396,8 +396,8 @@ public class DynamicColorSpecial implements DynamicColor { // nothing to do ... break; case REFLECT: - ratio -= (((int) (ratio)) >> 1) + 1; - if (ratio > 1.0f) { + ratio -= ((int) (ratio)) / 2 * 2.0f; + while (ratio > 1.0f) { ratio = 2.0f - ratio; } break; diff --git a/src/org/atriasoft/esvg/render/PathModel.java b/src/org/atriasoft/esvg/render/PathModel.java index 6b42bb8..e0038d8 100644 --- a/src/org/atriasoft/esvg/render/PathModel.java +++ b/src/org/atriasoft/esvg/render/PathModel.java @@ -3,10 +3,13 @@ package org.atriasoft.esvg.render; import java.util.ArrayList; import java.util.List; +import org.atriasoft.esvg.CapMode; +import org.atriasoft.esvg.JoinMode; import org.atriasoft.esvg.internal.Log; import org.atriasoft.etk.math.FMath; import org.atriasoft.etk.math.Matrix2x3f; import org.atriasoft.etk.math.Vector2f; +import org.atriasoft.etk.math.Vector2i; /** @file * @author Edouard DUPIN @@ -101,6 +104,32 @@ public class PathModel { } } + public Weight drawFill(final Vector2i size, final Matrix2x3f basicTrans, final int level, final RenderingConfig config) { + PointList listPoints = new PointList(); + listPoints = generateListPoints(level, config.recurtionMax(), config.interpolationThreshold()); + SegmentList listSegment = new SegmentList(); + Weight weight = new Weight(); + // Check if we need to display background + listSegment.createSegmentList(listPoints); + listSegment.applyMatrix(basicTrans); + // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule + weight.generate(size, config.numberOfScanline(), listSegment); + return weight; + } + + public Weight drawStroke(final Vector2i size, final Matrix2x3f basicTrans, final int level, final float strokeWidth, final RenderingConfig config) { + PointList listPoints = new PointList(); + listPoints = generateListPoints(level, config.recurtionMax(), config.interpolationThreshold()); + SegmentList listSegment = new SegmentList(); + Weight weight = new Weight(); + // Check if we need to display background + listSegment.createSegmentListStroke(listPoints, strokeWidth, CapMode.BUTT, JoinMode.MITER, 4.0f); + listSegment.applyMatrix(basicTrans); + // now, traverse the scanlines and find the intersections on each scanline, use non-zero rule + weight.generate(size, config.numberOfScanline(), listSegment); + return weight; + } + public void ellipticTo(final boolean relative, final Vector2f radius, final float angle, final boolean largeArcFlag, final boolean sweepFlag, final Vector2f pos) { this.listElement.add(new ElementElliptic(relative, radius, angle, largeArcFlag, sweepFlag, pos)); } diff --git a/src/org/atriasoft/esvg/render/PointList.java b/src/org/atriasoft/esvg/render/PointList.java index 92b4baf..15ffa1d 100644 --- a/src/org/atriasoft/esvg/render/PointList.java +++ b/src/org/atriasoft/esvg/render/PointList.java @@ -34,7 +34,7 @@ public class PointList { Log.warning(" Find List " + it.size() + " members"); for (int iii = 0; iii < it.size(); ++iii) { Point elem = it.get(iii); - Log.warning(" [" + iii + "] Find " + elem.type + " " + elem.pos); + Log.verbose(" [" + iii + "] Find " + elem.type + " " + elem.pos); } } } diff --git a/src/org/atriasoft/esvg/render/RenderingConfig.java b/src/org/atriasoft/esvg/render/RenderingConfig.java new file mode 100644 index 0000000..1a32793 --- /dev/null +++ b/src/org/atriasoft/esvg/render/RenderingConfig.java @@ -0,0 +1,6 @@ +package org.atriasoft.esvg.render; + +public record RenderingConfig( + int recurtionMax, + float interpolationThreshold, + int numberOfScanline) {} diff --git a/src/org/atriasoft/esvg/render/Weight.java b/src/org/atriasoft/esvg/render/Weight.java index 082027e..e03b1fe 100644 --- a/src/org/atriasoft/esvg/render/Weight.java +++ b/src/org/atriasoft/esvg/render/Weight.java @@ -37,6 +37,15 @@ public class Weight { ArraysTools.fill2(this.data, fill); } + public void fusion(final Weight redered, final int offsetXXX, final int offsetYYY) { + for (int yyy = 0; yyy < redered.getHeight(); yyy++) { + for (int xxx = 0; xxx < redered.getWidth(); xxx++) { + this.data[offsetYYY + yyy][offsetXXX + xxx] = FMath.avg(0.0f, this.data[offsetYYY + yyy][offsetXXX + xxx] + redered.get(xxx, yyy), 1.0f); + } + } + + } + public void generate(final Vector2i size, final int subSamplingCount, final SegmentList listSegment) { resize(size); // for each lines: @@ -143,6 +152,13 @@ public class Weight { } } + public float get(final int xxx, final int yyy) { + if (this.data == null) { + return 0; + } + return this.data[yyy][xxx]; + } + public float get(final Vector2i pos) { if (this.data == null) { return 0; diff --git a/test/src/test/atriasoft/esvg/ConfigTest.java b/test/src/test/atriasoft/esvg/ConfigTest.java index 966198e..e0f65cf 100644 --- a/test/src/test/atriasoft/esvg/ConfigTest.java +++ b/test/src/test/atriasoft/esvg/ConfigTest.java @@ -4,8 +4,10 @@ import java.awt.image.BufferedImage; import org.atriasoft.esvg.EsvgDocument; import org.atriasoft.esvg.internal.Log; +import org.atriasoft.esvg.render.Weight; import org.atriasoft.etk.Color; import org.atriasoft.etk.Uri; +import org.atriasoft.etk.math.Vector2i; import com.pngencoder.PngEncoder; @@ -32,5 +34,28 @@ public class ConfigTest { new PngEncoder().withBufferedImage(bufferedImage).withCompressionLevel(9).toFile(uri.getPath()); } + public static void generateAnImage(final Weight weight, final Uri uri) { + BufferedImage bufferedImage = new BufferedImage(weight.getWidth() + 2, weight.getHeight() + 2, BufferedImage.TYPE_INT_ARGB); + for (int yyy = 0; yyy < weight.getHeight(); yyy++) { + for (int xxx = 0; xxx < weight.getWidth(); xxx++) { + float elem = weight.get(new Vector2i(xxx, yyy)); + int tmpColor = (0xFF << 24) + ((int) (elem * 255.0f) << 16) + ((int) (elem * 255.0f) << 8) + ((int) (elem * 255.0f)); + bufferedImage.setRGB(xxx + 1, 1 + weight.getHeight() - 1 - yyy, tmpColor); + } + } + for (int yyy = 0; yyy < weight.getHeight() + 2; yyy++) { + bufferedImage.setRGB(0, yyy, 0xFFFF0000); + bufferedImage.setRGB(weight.getWidth() + 1, yyy, 0xFFFF0000); + } + for (int xxx = 0; xxx < weight.getWidth() + 2; xxx++) { + bufferedImage.setRGB(xxx, 0, 0xFFFF0000); + bufferedImage.setRGB(xxx, weight.getHeight() + 1, 0xFFFF0000); + } + Log.warning("Save file in " + uri.getPath()); + byte[] outElem = new PngEncoder().withBufferedImage(bufferedImage).withCompressionLevel(9).toBytes(); + Log.warning("outsize = " + outElem.length); + new PngEncoder().withBufferedImage(bufferedImage).withCompressionLevel(9).toFile(uri.getPath()); + } + private ConfigTest() {} } diff --git a/test/src/test/atriasoft/esvg/TestFont.java b/test/src/test/atriasoft/esvg/TestFont.java new file mode 100644 index 0000000..68b27f7 --- /dev/null +++ b/test/src/test/atriasoft/esvg/TestFont.java @@ -0,0 +1,93 @@ +package test.atriasoft.esvg; + +import org.atriasoft.esvg.Esvg; +import org.atriasoft.esvg.EsvgDocument; +import org.atriasoft.esvg.EsvgFont; +import org.atriasoft.esvg.render.Weight; +import org.atriasoft.etk.Uri; +import org.junit.jupiter.api.Test; + +class TestFont { + + @Test + public void testFontError1() { + String data = "" + "" + + " " + ""; + EsvgDocument doc = new EsvgDocument(); + doc.parse(data); + Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError1.svg"), data.replace("'", "\"")); + ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError1.png")); + } + + @Test + public void testFontError2() { + String data = "" + "" + + " " + + ""; + EsvgDocument doc = new EsvgDocument(); + doc.parse(data); + Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError2.svg"), data.replace("'", "\"")); + ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError2.png")); + } + + @Test + public void testFontError3() { + String data = "" + "" + + " " + ""; + EsvgDocument doc = new EsvgDocument(); + doc.parse(data); + Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError3.svg"), data.replace("'", "\"")); + ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError3.png")); + } + + @Test + public void testFontError4() { + String data = "" + "" + + " " + ""; + EsvgDocument doc = new EsvgDocument(); + doc.parse(data); + Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestFontError4.svg"), data.replace("'", "\"")); + ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestFontError4.png")); + } + + @Test + public void testFontprintE25() { + Esvg.init(); + EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg")); + Weight out = font.render('E', 25); + ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_E25.png")); + out = font.render('e', 25); + ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_e25.png")); + out = font.render('É', 25); + ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Ecute25.png")); + out = font.render('é', 25); + ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_ecute25.png")); + out = font.render('p', 25); + ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_p25.png")); + out = font.render('f', 25); + ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_f25.png")); + } + + @Test + public void testFontprintSimpleText() { + Esvg.init(); + EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg")); + Weight out = font.render("Hello, How are you? VA // @ ê É", 100, false); + ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Hello.png")); + out = font.render("Hello, How are you? VA // @ ê É", 100, true); + ConfigTest.generateAnImage(out, new Uri(ConfigTest.BASE_PATH + "testFontprint_Hello_withKerning.png")); + + } + + @Test + public void testFontRead() { + Esvg.init(); + EsvgFont font = EsvgFont.load(new Uri("FONTS", "FreeSherif.svg", "esvg")); + + } +} \ No newline at end of file diff --git a/test/src/test/atriasoft/esvg/TestPath.java b/test/src/test/atriasoft/esvg/TestPath.java index 9bc130a..da2586b 100644 --- a/test/src/test/atriasoft/esvg/TestPath.java +++ b/test/src/test/atriasoft/esvg/TestPath.java @@ -97,4 +97,5 @@ class TestPath { Uri.writeAll(new Uri(ConfigTest.BASE_PATH + "TestPathstroke.svg"), data.replace("'", "\"")); ConfigTest.generateAnImage(doc, new Uri(ConfigTest.BASE_PATH + "TestPathstroke.png")); } + } \ No newline at end of file