Skip to content
Snippets Groups Projects
Commit 0968af3c authored by Michael Fairchild's avatar Michael Fairchild
Browse files

Merge branch 'feature/issue-7' into 'develop'

Update unicode function to allow for ligatures

The code uses this unicode function in two places; first to read
the font and create a map of glyphs, and secondly to parse a string
into glyphs.

Fixes #7

See merge request !4
parents d910c69f 9fc91868
No related branches found
No related tags found
1 merge request!4Update unicode function to allow for ligatures
Pipeline #
...@@ -14,6 +14,12 @@ ...@@ -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. 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`. 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 ** ** Usage **
----------- -----------
......
...@@ -8,10 +8,10 @@ use \SvgGenerator as SVG; ...@@ -8,10 +8,10 @@ use \SvgGenerator as SVG;
class LockupsController extends Controller { class LockupsController extends Controller {
const LOCKUP_VERSION = '1.4'; const LOCKUP_VERSION = '1.5';
private static function checkTextFieldLength($params, $field, $max_length) { 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.'); self::flashNotice(parent::NOTICE_LEVEL_ERROR, 'Invalid Text', ucwords(implode(' ',explode('_', $field))) . ' must be ' . $max_length . ' characters or fewer.');
return FALSE; return FALSE;
} }
......
...@@ -45,27 +45,76 @@ class EasySVG { ...@@ -45,27 +45,76 @@ class EasySVG {
$values = array(); $values = array();
$lookingFor = 1; $lookingFor = 1;
for ($i = 0; $i < strlen( $str ); $i++ ) { $ligature_table = array(
$thisValue = ord( $str[ $i ] ); 'ff' => 64256, # = 0xFB00
if ( $thisValue < 128 ) $unicode[] = $thisValue; 'fi' => 64257,
else { 'fl' => 64258,
if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3; 'ffi' => 64259,
$values[] = $thisValue; 'ffl' => 64260,
if ( count( $values ) == $lookingFor ) { 'fb' => 64261,
$number = ( $lookingFor == 3 ) ? 'fh' => 64262,
( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ): 'fj' => 64263,
( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 ); 'fk' => 64264,
'ffb' => 64265,
$unicode[] = $number; 'ffh' => 64266,
$values = array(); 'ffj' => 64267,
$lookingFor = 1; '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; 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) * Set font params (short-hand method)
* @param string $filepath * @param string $filepath
...@@ -144,6 +193,7 @@ class EasySVG { ...@@ -144,6 +193,7 @@ class EasySVG {
if ($name == 'glyph') { if ($name == 'glyph') {
$unicode = $z->getAttribute('unicode'); $unicode = $z->getAttribute('unicode');
$unicode = html_entity_decode($unicode);
$unicode = $this->_utf8ToUnicode($unicode); $unicode = $this->_utf8ToUnicode($unicode);
if (count($unicode) > 0) { if (count($unicode) > 0) {
$unicode = $unicode[0]; $unicode = $unicode[0];
...@@ -212,6 +262,7 @@ class EasySVG { ...@@ -212,6 +262,7 @@ class EasySVG {
$horizAdvX = 0; $horizAdvX = 0;
$horizAdvY = $this->font->ascent + $this->font->descent; $horizAdvY = $this->font->ascent + $this->font->descent;
$fontSize = floatval($this->font->size) / $this->font->unitsPerEm; $fontSize = floatval($this->font->size) / $this->font->unitsPerEm;
$text = $this->_utf8ToUnicode($text); $text = $this->_utf8ToUnicode($text);
error_log(print_r($text, 1)); error_log(print_r($text, 1));
...@@ -227,8 +278,13 @@ class EasySVG { ...@@ -227,8 +278,13 @@ class EasySVG {
} }
// extract character definition // 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 // transform typo from original SVG format to straight display
$d = $this->defScale($d, $fontSize, -$fontSize); $d = $this->defScale($d, $fontSize, -$fontSize);
$d = $this->defTranslate($d, $horizAdvX, $horizAdvY*$fontSize*2); $d = $this->defTranslate($d, $horizAdvX, $horizAdvY*$fontSize*2);
...@@ -236,7 +292,7 @@ class EasySVG { ...@@ -236,7 +292,7 @@ class EasySVG {
$def[] = $d; $def[] = $d;
// next letter's position // 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); return implode(' ', $def);
} }
...@@ -271,7 +327,14 @@ class EasySVG { ...@@ -271,7 +327,14 @@ class EasySVG {
continue; 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 // only keep the widest line's width
......
<?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);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment