diff --git a/README.md b/README.md
index 841dc1fc14850e68284e7d480c060a3c94b88d9a..a625b7d57a639d2b5996798e25ccfb932ed3e6f3 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,12 @@
 11. This project uses `/public` instead of `/www` for its DocumentRoot, you may have to go into your httpd.conf files and change this. Look in `/etc/httpd/conf.d/` for a number-prefixed conf file.
 12. The server should now be running at `localhost:8009`.
 
+** Testing **
+-------------
+We are now striving for more unit testing. To run tests, please go to the
+root folder and type
+`phpunit --verbose --bootstrap config.inc.php tests`
+
 ** Usage **
 -----------
 
diff --git a/src/Controllers/LockupsController.php b/src/Controllers/LockupsController.php
index a0b1a2379606db843e77d47de5ae2f6abb8f5f52..c76e92a4576f85bd5e7bc25ce7fffd1f0f3d74d2 100644
--- a/src/Controllers/LockupsController.php
+++ b/src/Controllers/LockupsController.php
@@ -8,10 +8,10 @@ use \SvgGenerator as SVG;
 
 class LockupsController extends Controller {
 
-	const LOCKUP_VERSION = '1.4';
+	const LOCKUP_VERSION = '1.5';
 
 	private static function checkTextFieldLength($params, $field, $max_length) {
-		if (strlen($params[$field]) > $max_length) {
+		if (mb_strlen($params[$field]) > $max_length) {
 			self::flashNotice(parent::NOTICE_LEVEL_ERROR, 'Invalid Text', ucwords(implode(' ',explode('_', $field))) . ' must be ' . $max_length . ' characters or fewer.');
 			return FALSE;
 		}
diff --git a/src/EasySVG.php b/src/EasySVG.php
index a9a2c12acac8c638a0aa2be19eb73fd49302f492..0edd499b2a246df77cffb158661699a70bedcbc2 100644
--- a/src/EasySVG.php
+++ b/src/EasySVG.php
@@ -40,32 +40,81 @@ class EasySVG {
      * @param  string $str
      * @return string
      */
-    private function _utf8ToUnicode( $str ) {
+    private function _utf8ToUnicode($str) {
         $unicode = array();
         $values = array();
         $lookingFor = 1;
 
-        for ($i = 0; $i < strlen( $str ); $i++ ) {
-            $thisValue = ord( $str[ $i ] );
-            if ( $thisValue < 128 ) $unicode[] = $thisValue;
-            else {
-                if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3;
-                $values[] = $thisValue;
-                if ( count( $values ) == $lookingFor ) {
-                    $number = ( $lookingFor == 3 ) ?
-                        ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ):
-                        ( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 );
-
-                    $unicode[] = $number;
-                    $values = array();
-                    $lookingFor = 1;
+        $ligature_table = array(
+            'ff' => 64256, # = 0xFB00
+            'fi' => 64257,
+            'fl' => 64258,
+            'ffi' => 64259,
+            'ffl' => 64260,
+            'fb' => 64261,
+            'fh' => 64262,
+            'fj' => 64263,
+            'fk' => 64264,
+            'ffb' => 64265,
+            'ffh' => 64266,
+            'ffj' => 64267,
+            'ffk' => 64268
+        );
+
+        for ($i = 0; $i < mb_strlen($str); $i++ ) {
+            # check for ligatures here
+            # ------ THIS IS KIND OF A HACK ----- #
+            # see Unicode only supports ff, fi, fl, ffi, and ffl ligatures. However, certain unicode characters near these are unused.
+            # so I use these codes to correspond to other ligatures as given below. 
+            # See https://en.wikipedia.org/wiki/Typographic_ligature#Ligatures_in_Unicode_.28Latin_alphabets.29
+            # ---------------------------------------------------------------------------------------------------------------------- #
+            # |   fb   |   ff   |   fh   |   fi   |   fj   |   fk   |   fl   |   ffb  |   ffh  |   ffi  |   ffj  |   ffk  |   ffl  | #
+            # |--------------------------------------------------------------------------------------------------------------------| #
+            # | 0xFB05 | 0xFB00 | 0xFB06 | 0xFB01 | 0xFB07 | 0xFB08 | 0xFB02 | 0xFB09 | 0xFB0A | 0xFB03 | 0xFB0B | 0xFB0C | 0xFB04 | #
+            # |--------------------------------------------------------------------------------------------------------------------| #
+
+            if (mb_substr($str, $i, 1) == 'f') {
+                if (mb_strlen($str) > $i+1 && in_array(mb_substr($str, $i+1, 1), array('b','h','i','j','k','l'))) {
+                    $unicode[] = $ligature_table[mb_substr($str, $i, 2)];
+                    $i++;
+                    continue;
+                } else if (mb_strlen($str) > $i+1 && mb_substr($str, $i+1, 1) == 'f') {
+                    if (mb_strlen($str) > $i+2 && in_array(mb_substr($str, $i+2, 1), array('b','h','i','j','k','l'))) {
+                        $unicode[] = $ligature_table[mb_substr($str, $i, 3)];
+                        $i += 2;
+                        continue;
+                    } else {
+                        $unicode[] = $ligature_table['ff'];
+                        $i++;
+                        continue;
+                    }
                 }
             }
+
+            $unicode[] = $this->_unicodeOrd(mb_substr($str, $i, 1));
         }
 
         return $unicode;
     }
 
+    private function _unicodeOrd($c) {
+        if (ord($c[0]) >=0 && ord($c[0]) <= 127)
+            return ord($c[0]);
+        if (ord($c[0]) >= 192 && ord($c[0]) <= 223)
+            return (ord($c[0])-192)*64 + (ord($c[1])-128);
+        if (ord($c[0]) >= 224 && ord($c[0]) <= 239)
+            return (ord($c[0])-224)*4096 + (ord($c[1])-128)*64 + (ord($c[2])-128);
+        if (ord($c[0]) >= 240 && ord($c[0]) <= 247)
+            return (ord($c[0])-240)*262144 + (ord($c[1])-128)*4096 + (ord($c[2])-128)*64 + (ord($c[3])-128);
+        if (ord($c[0]) >= 248 && ord($c[0]) <= 251)
+            return (ord($c[0])-248)*16777216 + (ord($c[1])-128)*262144 + (ord($c[2])-128)*4096 + (ord($c[3])-128)*64 + (ord($c[4])-128);
+        if (ord($c[0]) >= 252 && ord($c[0]) <= 253)
+            return (ord($c[0])-252)*1073741824 + (ord($c[1])-128)*16777216 + (ord($c[2])-128)*262144 + (ord($c[3])-128)*4096 + (ord($c[4])-128)*64 + (ord($c[5])-128);
+        if (ord($c[0]) >= 254 && ord($c[0]) <= 255)    //  error
+            return FALSE;
+        return 0;
+    }
+
     /**
      * Set font params (short-hand method)
      * @param string $filepath
@@ -144,6 +193,7 @@ class EasySVG {
 
                 if ($name == 'glyph') {
                     $unicode = $z->getAttribute('unicode');
+                    $unicode = html_entity_decode($unicode);
                     $unicode = $this->_utf8ToUnicode($unicode);
                     if (count($unicode) > 0) {
                         $unicode = $unicode[0];
@@ -212,8 +262,9 @@ class EasySVG {
         $horizAdvX = 0;
         $horizAdvY = $this->font->ascent + $this->font->descent;
         $fontSize = floatval($this->font->size) / $this->font->unitsPerEm;
+
         $text = $this->_utf8ToUnicode($text);
-        error_log(print_r($text,1));
+        error_log(print_r($text, 1));
 
         for($i = 0; $i < count($text); $i++) {
 
@@ -227,8 +278,13 @@ class EasySVG {
             }
             
             // extract character definition
-            $d = $this->font->glyphs[$letter]->d;
+            if (isset($this->font->glyphs[$letter])) {
+                $letter = $this->font->glyphs[$letter];
+            } else {
+                $letter = $this->font->glyphs[32];
+            }
 
+            $d = $letter->d;
             // transform typo from original SVG format to straight display
             $d = $this->defScale($d, $fontSize, -$fontSize);
             $d = $this->defTranslate($d, $horizAdvX, $horizAdvY*$fontSize*2);
@@ -236,7 +292,7 @@ class EasySVG {
             $def[] = $d;
 
             // next letter's position
-            $horizAdvX += $this->font->glyphs[$letter]->horizAdvX * $fontSize + $this->font->em * $this->font->letterSpacing * $fontSize;
+            $horizAdvX += $letter->horizAdvX * $fontSize + $this->font->em * $this->font->letterSpacing * $fontSize;
         }
         return implode(' ', $def);
     }
@@ -271,7 +327,14 @@ class EasySVG {
                 continue;
             }
 
-            $lineWidth += $this->font->glyphs[$letter]->horizAdvX * $fontSize + $this->font->em * $this->font->letterSpacing * $fontSize;
+            // extract character definition
+            if (isset($this->font->glyphs[$letter])) {
+                $letter = $this->font->glyphs[$letter];
+            } else {
+                $letter = $this->font->glyphs[32];
+            }
+
+            $lineWidth += $letter->horizAdvX * $fontSize + $this->font->em * $this->font->letterSpacing * $fontSize;
         }
 
         // only keep the widest line's width
diff --git a/tests/EasySVGUTF8ToUnicodeTest.php b/tests/EasySVGUTF8ToUnicodeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..362211c81a4d3c03f9f9ef14c4883364b6da5921
--- /dev/null
+++ b/tests/EasySVGUTF8ToUnicodeTest.php
@@ -0,0 +1,52 @@
+<?php
+
+class EasySVGUTF8ToUnicodeTest extends \PHPUnit_Framework_TestCase {
+    protected $svg;
+    protected $reflection;
+
+    protected function setUp() {
+        $this->svg = new EasySVG;
+        $this->reflection = new \ReflectionClass(get_class($this->svg));
+    }
+
+    protected function runUTF8Method($string) {
+        $method = $this->reflection->getMethod('_utf8ToUnicode');
+        $method->setAccessible(true);
+        return $method->invokeArgs($this->svg, array($string));
+    }
+
+    public function testStandardCharacters() {
+        $result = $this->runUTF8Method('omg lol');
+        $this->assertEquals(array(
+            111,109,103,32,108,111,108
+        ), $result);
+    }
+
+    public function testStrangeASCII() {
+        $result = $this->runUTF8Method('ümlaut eñye');
+        $this->assertEquals(array(
+            252,109,108,97,117,116,32,101,241,121,101
+        ), $result);
+    }
+
+    public function testLigatures() {
+        $result = $this->runUTF8Method('ff fb fj fi fj fk fl ffb ffj ffi ffj ffk ffl fff');
+        $this->assertEquals(array(
+            64256,32,
+            64261,32,
+            64263,32,
+            64257,32,
+            64263,32,
+            64264,32,
+            64258,32,
+            64265,32,
+            64267,32,
+            64259,32,
+            64267,32,
+            64268,32,
+            64260,32,
+            64256,102
+        ), $result);
+    }
+}
+