72        public static function addTTFfont($fontfile, $fonttype=
'', $enc=
'', $flags=32, $outpath=
'', $platid=3, $encid=1, $addcbbox=
false, $link=
false) {
 
   73                if (!file_exists($fontfile)) {
 
   80                $font_path_parts = pathinfo($fontfile);
 
   81                if (!isset($font_path_parts[
'filename'])) {
 
   82                        $font_path_parts[
'filename'] = substr($font_path_parts[
'basename'], 0, -(strlen($font_path_parts[
'extension']) + 1));
 
   84                $font_name = strtolower($font_path_parts[
'filename']);
 
   85                $font_name = preg_replace(
'/[^a-z0-9_]/', 
'', $font_name);
 
   86                $search  = array(
'bold', 
'oblique', 
'italic', 
'regular');
 
   87                $replace = array(
'b', 
'i', 
'i', 
'');
 
   88                $font_name = str_replace($search, $replace, $font_name);
 
   89                if (empty($font_name)) {
 
   91                        $font_name = 
'tcpdffont';
 
   94                if (empty($outpath)) {
 
   98                if (@file_exists($outpath.$font_name.
'.php')) {
 
  102                $fmetric[
'file'] = $font_name;
 
  103                $fmetric[
'ctg'] = $font_name.
'.ctg.z';
 
  105                $font = file_get_contents($fontfile);
 
  106                $fmetric[
'originalsize'] = strlen($font);
 
  108                if (empty($fonttype)) {
 
  111                                $fonttype = 
'TrueTypeUnicode';
 
  112                        } elseif (substr($font, 0, 4) == 
'OTTO') {
 
  127                                $fmetric[
'type'] = 
'cidfont0';
 
  131                                $fmetric[
'type'] = 
'Type1';
 
  132                                if (empty($enc) AND (($flags & 4) == 0)) {
 
  138                                $fmetric[
'type'] = 
'TrueType';
 
  141                        case 'TrueTypeUnicode':
 
  143                                $fmetric[
'type'] = 
'TrueTypeUnicode';
 
  148                $fmetric[
'enc'] = preg_replace(
'/[^A-Za-z0-9_\-]/', 
'', $enc);
 
  149                $fmetric[
'diff'] = 
'';
 
  150                if (($fmetric[
'type'] == 
'TrueType') OR ($fmetric[
'type'] == 
'Type1')) {
 
  156                                for (
$i = 32; 
$i <= 255; ++
$i) {
 
  157                                        if ($enc_target[
$i] != $enc_ref[
$i]) {
 
  158                                                if (
$i != ($last + 1)) {
 
  159                                                        $fmetric[
'diff'] .= 
$i.
' ';
 
  162                                                $fmetric[
'diff'] .= 
'/'.$enc_target[
$i].
' ';
 
  168                if ($fmetric[
'type'] == 
'Type1') {
 
  171                        $a = unpack(
'Cmarker/Ctype/Vsize', substr($font, 0, 6));
 
  172                        if ($a[
'marker'] != 128) {
 
  176                        $fmetric[
'size1'] = $a[
'size'];
 
  177                        $data = substr($font, 6, $fmetric[
'size1']);
 
  179                        $a = unpack(
'Cmarker/Ctype/Vsize', substr($font, (6 + $fmetric[
'size1']), 6));
 
  180                        if ($a[
'marker'] != 128) {
 
  184                        $fmetric[
'size2'] = $a[
'size'];
 
  185                        $encrypted = substr($font, (12 + $fmetric[
'size1']), $fmetric[
'size2']);
 
  188                        $fmetric[
'file'] .= 
'.z';
 
  190                        fwrite($fp, gzcompress(
$data));
 
  193                        $fmetric[
'Flags'] = $flags;
 
  194                        preg_match (
'#/FullName[\s]*\(([^\)]*)#', $font, $matches);
 
  195                        $fmetric[
'name'] = preg_replace(
'/[^a-zA-Z0-9_\-]/', 
'', $matches[1]);
 
  196                        preg_match(
'#/FontBBox[\s]*{([^}]*)#', $font, $matches);
 
  197                        $fmetric[
'bbox'] = trim($matches[1]);
 
  198                        $bv = explode(
' ', $fmetric[
'bbox']);
 
  199                        $fmetric[
'Ascent'] = intval($bv[3]);
 
  200                        $fmetric[
'Descent'] = intval($bv[1]);
 
  201                        preg_match(
'#/ItalicAngle[\s]*([0-9\+\-]*)#', $font, $matches);
 
  202                        $fmetric[
'italicAngle'] = intval($matches[1]);
 
  203                        if ($fmetric[
'italicAngle'] != 0) {
 
  204                                $fmetric[
'Flags'] |= 64;
 
  206                        preg_match(
'#/UnderlinePosition[\s]*([0-9\+\-]*)#', $font, $matches);
 
  207                        $fmetric[
'underlinePosition'] = intval($matches[1]);
 
  208                        preg_match(
'#/UnderlineThickness[\s]*([0-9\+\-]*)#', $font, $matches);
 
  209                        $fmetric[
'underlineThickness'] = intval($matches[1]);
 
  210                        preg_match(
'#/isFixedPitch[\s]*([^\s]*)#', $font, $matches);
 
  211                        if ($matches[1] == 
'true') {
 
  212                                $fmetric[
'Flags'] |= 1;
 
  216                        if (preg_match_all(
'#dup[\s]([0-9]+)[\s]*/([^\s]*)[\s]put#sU', $font, $fmap, PREG_SET_ORDER) > 0) {
 
  217                                foreach ($fmap as $v) {
 
  218                                        $imap[$v[2]] = $v[1];
 
  225                        $elen = strlen($encrypted);
 
  227                        for (
$i = 0; 
$i < $elen; ++
$i) {
 
  228                                $chr = ord($encrypted[
$i]);
 
  229                                $eplain .= chr($chr ^ (
$r >> 8));
 
  230                                $r = ((($chr + 
$r) * $c1 + $c2) % 65536);
 
  232                        if (preg_match(
'#/ForceBold[\s]*([^\s]*)#', $eplain, $matches) > 0) {
 
  233                                if ($matches[1] == 
'true') {
 
  234                                        $fmetric[
'Flags'] |= 0x40000;
 
  237                        if (preg_match(
'#/StdVW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
 
  238                                $fmetric[
'StemV'] = intval($matches[1]);
 
  240                                $fmetric[
'StemV'] = 70;
 
  242                        if (preg_match(
'#/StdHW[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
 
  243                                $fmetric[
'StemH'] = intval($matches[1]);
 
  245                                $fmetric[
'StemH'] = 30;
 
  247                        if (preg_match(
'#/BlueValues[\s]*\[([^\]]*)#', $eplain, $matches) > 0) {
 
  248                                $bv = explode(
' ', $matches[1]);
 
  249                                if (count($bv) >= 6) {
 
  250                                        $v1 = intval($bv[2]);
 
  251                                        $v2 = intval($bv[4]);
 
  253                                                $fmetric[
'XHeight'] = $v1;
 
  254                                                $fmetric[
'CapHeight'] = $v2;
 
  256                                                $fmetric[
'XHeight'] = $v2;
 
  257                                                $fmetric[
'CapHeight'] = $v1;
 
  260                                        $fmetric[
'XHeight'] = 450;
 
  261                                        $fmetric[
'CapHeight'] = 700;
 
  264                                $fmetric[
'XHeight'] = 450;
 
  265                                $fmetric[
'CapHeight'] = 700;
 
  268                        if (preg_match(
'#/lenIV[\s]*([0-9]*)#', $eplain, $matches) > 0) {
 
  269                                $lenIV = intval($matches[1]);
 
  273                        $fmetric[
'Leading'] = 0;
 
  275                        $eplain = substr($eplain, (strpos($eplain, 
'/CharStrings') + 1));
 
  276                        preg_match_all(
'#/([A-Za-z0-9\.]*)[\s][0-9]+[\s]RD[\s](.*)[\s]ND#sU', $eplain, $matches, PREG_SET_ORDER);
 
  283                        $fmetric[
'MaxWidth'] = 0;
 
  285                        foreach ($matches as $k => $v) {
 
  287                                if (isset($imap[$v[1]])) {
 
  289                                } elseif ($enc_map !== 
false) {
 
  290                                        $cid = array_search($v[1], $enc_map);
 
  291                                        if ($cid === 
false) {
 
  293                                        } elseif ($cid > 1000) {
 
  304                                for (
$i = 0; 
$i < $clen; ++
$i) {
 
  306                                        $ccom[] = ($chr ^ (
$r >> 8));
 
  307                                        $r = ((($chr + 
$r) * $c1 + $c2) % 65536);
 
  314                                        if ($ccom[
$i] < 32) {
 
  315                                                $cdec[$ck] = $ccom[
$i];
 
  316                                                if (($ck > 0) AND ($cdec[$ck] == 13)) {
 
  318                                                        $cwidths[$cid] = $cdec[($ck - 1)];
 
  321                                        } elseif (($ccom[
$i] >= 32) AND ($ccom[
$i] <= 246)) {
 
  322                                                $cdec[$ck] = ($ccom[
$i] - 139);
 
  324                                        } elseif (($ccom[
$i] >= 247) AND ($ccom[
$i] <= 250)) {
 
  325                                                $cdec[$ck] = ((($ccom[
$i] - 247) * 256) + $ccom[(
$i + 1)] + 108);
 
  327                                        } elseif (($ccom[
$i] >= 251) AND ($ccom[
$i] <= 254)) {
 
  328                                                $cdec[$ck] = ((-($ccom[
$i] - 251) * 256) - $ccom[(
$i + 1)] - 108);
 
  330                                        } elseif ($ccom[
$i] == 255) {
 
  331                                                $sval = chr($ccom[(
$i + 1)]).chr($ccom[(
$i + 2)]).chr($ccom[(
$i + 3)]).chr($ccom[(
$i + 4)]);
 
  332                                                $vsval = unpack(
'li', $sval);
 
  333                                                $cdec[$ck] = $vsval[
'i'];
 
  339                        $fmetric[
'MissingWidth'] = $cwidths[0];
 
  340                        $fmetric[
'MaxWidth'] = $fmetric[
'MissingWidth'];
 
  341                        $fmetric[
'AvgWidth'] = 0;
 
  343                        for ($cid = 0; $cid <= 255; ++$cid) {
 
  344                                if (isset($cwidths[$cid])) {
 
  345                                        if ($cwidths[$cid] > $fmetric[
'MaxWidth']) {
 
  346                                                $fmetric[
'MaxWidth'] = $cwidths[$cid];
 
  348                                        $fmetric[
'AvgWidth'] += $cwidths[$cid];
 
  349                                        $fmetric[
'cw'] .= 
','.$cid.
'=>'.$cwidths[$cid];
 
  351                                        $fmetric[
'cw'] .= 
','.$cid.
'=>'.$fmetric[
'MissingWidth'];
 
  354                        $fmetric[
'AvgWidth'] = round($fmetric[
'AvgWidth'] / count($cwidths));
 
  362                        if ($fmetric[
'type'] != 
'cidfont0') {
 
  365                                        symlink($fontfile, $outpath.$fmetric[
'file']);
 
  368                                        $fmetric[
'file'] .= 
'.z';
 
  370                                        fwrite($fp, gzcompress($font));
 
  383                        for (
$i = 0; 
$i < $numTables; ++
$i) {
 
  385                                $tag = substr($font, $offset, 4);
 
  396                        $offset = 
$table[
'head'][
'offset'] + 12;
 
  407                        $urk = (1000 / $fmetric[
'unitsPerEm']);
 
  417                        $fmetric[
'bbox'] = 
''.$xMin.
' '.$yMin.
' '.$xMax.
' '.$yMax.
'';
 
  421                        $fmetric[
'Flags'] = $flags;
 
  422                        if (($macStyle & 2) == 2) {
 
  424                                $fmetric[
'Flags'] |= 64;
 
  427                        $offset = 
$table[
'head'][
'offset'] + 50;
 
  431                        $indexToLoc = array();
 
  432                        $offset = 
$table[
'loca'][
'offset'];
 
  435                                $tot_num_glyphs = floor(
$table[
'loca'][
'length'] / 2); 
 
  436                                for (
$i = 0; 
$i < $tot_num_glyphs; ++
$i) {
 
  438                                        if (isset($indexToLoc[(
$i - 1)]) && ($indexToLoc[
$i] == $indexToLoc[(
$i - 1)])) {
 
  440                                                unset($indexToLoc[(
$i - 1)]);
 
  446                                $tot_num_glyphs = floor(
$table[
'loca'][
'length'] / 4); 
 
  447                                for (
$i = 0; 
$i < $tot_num_glyphs; ++
$i) {
 
  449                                        if (isset($indexToLoc[(
$i - 1)]) && ($indexToLoc[
$i] == $indexToLoc[(
$i - 1)])) {
 
  451                                                unset($indexToLoc[(
$i - 1)]);
 
  457                        $offset = 
$table[
'cmap'][
'offset'] + 2;
 
  460                        $encodingTables = array();
 
  461                        for (
$i = 0; 
$i < $numEncodingTables; ++
$i) {
 
  470                        $offset = 
$table[
'OS/2'][
'offset'];
 
  478                        $fmetric[
'StemV'] = round((70 * $usWeightClass) / 400);
 
  479                        $fmetric[
'StemH'] = round((30 * $usWeightClass) / 400);
 
  489                        $fmetric[
'name'] = 
'';
 
  490                        $offset = 
$table[
'name'][
'offset'];
 
  498                        for (
$i = 0; 
$i < $numNameRecords; ++
$i) {
 
  510                                        $offset = (
$table[
'name'][
'offset'] + $stringStorageOffset + $stringOffset);
 
  511                                        $fmetric[
'name'] = substr($font, $offset, $stringLength);
 
  512                                        $fmetric[
'name'] = preg_replace(
'/[^a-zA-Z0-9_\-]/', 
'', $fmetric[
'name']);
 
  518                        if (empty($fmetric[
'name'])) {
 
  519                                $fmetric[
'name'] = $font_name;
 
  522                        $offset = 
$table[
'post'][
'offset'];
 
  533                                $fmetric[
'Flags'] |= 1;
 
  536                        $offset = 
$table[
'hhea'][
'offset'];
 
  554                        $offset = 
$table[
'maxp'][
'offset'];
 
  560                        foreach ($encodingTables as $enctable) {
 
  562                                if (($enctable[
'platformID'] == $platid) AND ($enctable[
'encodingID'] == $encid)) {
 
  563                                        $offset = 
$table[
'cmap'][
'offset'] + $enctable[
'offset'];
 
  569                                                        for (
$c = 0; 
$c < 256; ++
$c) {
 
  579                                                        for (
$i = 0; 
$i < 256; ++
$i) {
 
  583                                                                if ($numSubHeaders < $subHeaderKeys[
$i]) {
 
  584                                                                        $numSubHeaders = $subHeaderKeys[
$i];
 
  590                                                        $subHeaders = array();
 
  591                                                        $numGlyphIndexArray = 0;
 
  592                                                        for ($k = 0; $k < $numSubHeaders; ++$k) {
 
  601                                                                $subHeaders[$k][
'idRangeOffset'] -= (2 + (($numSubHeaders - $k - 1) * 8));
 
  602                                                                $subHeaders[$k][
'idRangeOffset'] /= 2;
 
  603                                                                $numGlyphIndexArray += $subHeaders[$k][
'entryCount'];
 
  605                                                        for ($k = 0; $k < $numGlyphIndexArray; ++$k) {
 
  609                                                        for (
$i = 0; 
$i < 256; ++
$i) {
 
  610                                                                $k = $subHeaderKeys[
$i];
 
  614                                                                        $g = $glyphIndexArray[0];
 
  618                                                                        $start_byte = $subHeaders[$k][
'firstCode'];
 
  619                                                                        $end_byte = $start_byte + $subHeaders[$k][
'entryCount'];
 
  620                                                                        for ($j = $start_byte; $j < $end_byte; ++$j) {
 
  622                                                                                $c = ((
$i << 8) + $j);
 
  623                                                                                $idRangeOffset = ($subHeaders[$k][
'idRangeOffset'] + $j - $subHeaders[$k][
'firstCode']);
 
  624                                                                                $g = ($glyphIndexArray[$idRangeOffset] + $subHeaders[$k][
'idDelta']) % 65536;
 
  642                                                        for ($k = 0; $k < $segCount; ++$k) {
 
  647                                                        $startCount = array(); 
 
  648                                                        for ($k = 0; $k < $segCount; ++$k) {
 
  653                                                        for ($k = 0; $k < $segCount; ++$k) {
 
  657                                                        $idRangeOffset = array(); 
 
  658                                                        for ($k = 0; $k < $segCount; ++$k) {
 
  662                                                        $gidlen = (floor($length / 2) - 8 - (4 * $segCount));
 
  663                                                        $glyphIdArray = array(); 
 
  664                                                        for ($k = 0; $k < $gidlen; ++$k) {
 
  668                                                        for ($k = 0; $k < $segCount; ++$k) {
 
  669                                                                for (
$c = $startCount[$k]; 
$c <= $endCount[$k]; ++
$c) {
 
  670                                                                        if ($idRangeOffset[$k] == 0) {
 
  671                                                                                $g = ($idDelta[$k] + 
$c) % 65536;
 
  673                                                                                $gid = (floor($idRangeOffset[$k] / 2) + (
$c - $startCount[$k]) - ($segCount - $k));
 
  674                                                                                $g = ($glyphIdArray[$gid] + $idDelta[$k]) % 65536;
 
  690                                                        for ($k = 0; $k < $entryCount; ++$k) {
 
  691                                                                $c = ($k + $firstCode);
 
  700                                                        for ($k = 0; $k < 8192; ++$k) {
 
  706                                                        for (
$i = 0; 
$i < $nGroups; ++
$i) {
 
  713                                                                for ($k = $startCharCode; $k <= $endCharCode; ++$k) {
 
  714                                                                        $is32idx = floor(
$c / 8);
 
  715                                                                        if ((isset($is32[$is32idx])) AND (($is32[$is32idx] & (1 << (7 - (
$c % 8)))) == 0)) {
 
  722                                                                                $c = ((55232 + ($k >> 10)) << 10) + (0xDC00 + ($k & 0x3FF)) -56613888;
 
  736                                                        for ($k = 0; $k < $numChars; ++$k) {
 
  737                                                                $c = ($k + $startCharCode);
 
  748                                                        for ($k = 0; $k < $nGroups; ++$k) {
 
  755                                                                for (
$c = $startCharCode; 
$c <= $endCharCode; ++
$c) {
 
  756                                                                        $ctg[
$c] = $startGlyphCode;
 
  773                        if (!isset($ctg[0])) {
 
  777                        $offset = (
$table[
'glyf'][
'offset'] + $indexToLoc[$ctg[120]] + 4);
 
  782                        $fmetric[
'XHeight'] = round(($yMax - $yMin) * $urk);
 
  784                        $offset = (
$table[
'glyf'][
'offset'] + $indexToLoc[$ctg[72]] + 4);
 
  789                        $fmetric[
'CapHeight'] = round(($yMax - $yMin) * $urk);
 
  792                        $offset = 
$table[
'hmtx'][
'offset'];
 
  793                        for (
$i = 0 ; 
$i < $numberOfHMetrics; ++
$i) {
 
  797                        if ($numberOfHMetrics < $numGlyphs) {
 
  799                                $cw = array_pad($cw, $numGlyphs, $cw[($numberOfHMetrics - 1)]);
 
  801                        $fmetric[
'MissingWidth'] = $cw[0];
 
  803                        $fmetric[
'cbbox'] = 
'';
 
  804                        for ($cid = 0; $cid <= 65535; ++$cid) {
 
  805                                if (isset($ctg[$cid])) {
 
  806                                        if (isset($cw[$ctg[$cid]])) {
 
  807                                                $fmetric[
'cw'] .= 
','.$cid.
'=>'.$cw[$ctg[$cid]];
 
  809                                        if ($addcbbox AND isset($indexToLoc[$ctg[$cid]])) {
 
  810                                                $offset = (
$table[
'glyf'][
'offset'] + $indexToLoc[$ctg[$cid]]);
 
  815                                                $fmetric[
'cbbox'] .= 
','.$cid.
'=>array('.$xMin.
','.$yMin.
','.$xMax.
','.$yMax.
')';
 
  820                if (($fmetric[
'type'] == 
'TrueTypeUnicode') AND (count($ctg) == 256)) {
 
  821                        $fmetric[
'type'] = 
'TrueType';
 
  824                $pfile = 
'<'.
'?'.
'php'.
"\n";
 
  825                $pfile .= 
'// TCPDF FONT FILE DESCRIPTION'.
"\n";
 
  826                $pfile .= 
'$type=\''.$fmetric[
'type'].
'\';
'."\n"; 
  827                $pfile .= '$name=\
''.$fmetric[
'name'].
'\';
'."\n"; 
  828                $pfile .= '$up=
'.$fmetric['underlinePosition
'].';
'."\n"; 
  829                $pfile .= '$ut=
'.$fmetric['underlineThickness
'].';
'."\n"; 
  830                if ($fmetric['MissingWidth
'] > 0) { 
  831                        $pfile .= '$dw=
'.$fmetric['MissingWidth
'].';
'."\n"; 
  833                        $pfile .= '$dw=
'.$fmetric['AvgWidth
'].';
'."\n"; 
  835                $pfile .= '$diff=\
''.$fmetric[
'diff'].
'\';
'."\n"; 
  836                if ($fmetric['type
'] == 'Type1
') { 
  838                        $pfile .= '$enc=\
''.$fmetric[
'enc'].
'\';
'."\n"; 
  839                        $pfile .= '$file=\
''.$fmetric[
'file'].
'\';
'."\n"; 
  840                        $pfile .= '$size1=
'.$fmetric['size1
'].';
'."\n"; 
  841                        $pfile .= '$size2=
'.$fmetric['size2
'].';
'."\n"; 
  843                        $pfile .= '$originalsize=
'.$fmetric['originalsize
'].';
'."\n"; 
  844                        if ($fmetric['type
'] == 'cidfont0
') { 
  849                                                $pfile .= 
'$enc=\'UniJIS-UTF16-H\';'.
"\n";
 
  850                                                $pfile .= 
'$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'Japan1\',\'Supplement\'=>5);'.
"\n";
 
  851                                                $pfile .= 
'include(dirname(__FILE__).\'/uni2cid_aj16.php\');'.
"\n";
 
  855                                                $pfile .= 
'// Korean'.
"\n";
 
  856                                                $pfile .= 
'$enc=\'UniKS-UTF16-H\';'.
"\n";
 
  857                                                $pfile .= 
'$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'Korea1\',\'Supplement\'=>0);'.
"\n";
 
  858                                                $pfile .= 
'include(dirname(__FILE__).\'/uni2cid_ak12.php\');'.
"\n";
 
  862                                                $pfile .= 
'// Chinese Simplified'.
"\n";
 
  863                                                $pfile .= 
'$enc=\'UniGB-UTF16-H\';'.
"\n";
 
  864                                                $pfile .= 
'$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'GB1\',\'Supplement\'=>2);'.
"\n";
 
  865                                                $pfile .= 
'include(dirname(__FILE__).\'/uni2cid_ag15.php\');'.
"\n";
 
  870                                                $pfile .= 
'// Chinese Traditional'.
"\n";
 
  871                                                $pfile .= 
'$enc=\'UniCNS-UTF16-H\';'.
"\n";
 
  872                                                $pfile .= 
'$cidinfo=array(\'Registry\'=>\'Adobe\', \'Ordering\'=>\'CNS1\',\'Supplement\'=>0);'.
"\n";
 
  873                                                $pfile .= 
'include(dirname(__FILE__).\'/uni2cid_aj16.php\');'.
"\n";
 
  879                                $pfile .= 
'$enc=\''.$fmetric[
'enc'].
'\';
'."\n"; 
  880                                $pfile .= '$file=\
''.$fmetric[
'file'].
'\';
'."\n"; 
  881                                $pfile .= '$ctg=\
''.$fmetric[
'ctg'].
'\';
'."\n"; 
  882                                // create CIDToGIDMap 
  883                                $cidtogidmap = str_pad('', 131072, "\x00"); // (256 * 256 * 2) = 131072 
  884                                foreach ($ctg as $cid => $gid) { 
  885                                        $cidtogidmap = self::updateCIDtoGIDmap($cidtogidmap, $cid, $ctg[$cid]); 
  887                                // store compressed CIDToGIDMap 
  888                                $fp = TCPDF_STATIC::fopenLocal($outpath.$fmetric['ctg
'], 'wb
'); 
  889                                fwrite($fp, gzcompress($cidtogidmap)); 
  893                $pfile .= '$desc=array(
'; 
  894                $pfile .= '\
'Flags\'=>'.$fmetric[
'Flags'].
',';
 
  895                $pfile .= 
'\'FontBBox\
'=>\'['.$fmetric[
'bbox'].
']\',';
 
  896                $pfile .= 
'\'ItalicAngle\
'=>'.$fmetric[
'italicAngle'].
',';
 
  897                $pfile .= 
'\'Ascent\
'=>'.$fmetric[
'Ascent'].
',';
 
  898                $pfile .= 
'\'Descent\
'=>'.$fmetric[
'Descent'].
',';
 
  899                $pfile .= 
'\'Leading\
'=>'.$fmetric[
'Leading'].
',';
 
  900                $pfile .= 
'\'CapHeight\
'=>'.$fmetric[
'CapHeight'].
',';
 
  901                $pfile .= 
'\'XHeight\
'=>'.$fmetric[
'XHeight'].
',';
 
  902                $pfile .= 
'\'StemV\
'=>'.$fmetric[
'StemV'].
',';
 
  903                $pfile .= 
'\'StemH\
'=>'.$fmetric[
'StemH'].
',';
 
  904                $pfile .= 
'\'AvgWidth\
'=>'.$fmetric[
'AvgWidth'].
',';
 
  905                $pfile .= 
'\'MaxWidth\
'=>'.$fmetric[
'MaxWidth'].
',';
 
  906                $pfile .= 
'\'MissingWidth\
'=>'.$fmetric[
'MissingWidth'].
'';
 
  908                if (!empty($fmetric[
'cbbox'])) {
 
  909                        $pfile .= 
'$cbbox=array('.substr($fmetric[
'cbbox'], 1).
');'.
"\n";
 
  911                $pfile .= 
'$cw=array('.substr($fmetric[
'cw'], 1).
');'.
"\n";
 
  912                $pfile .= 
'// --- EOF ---'.
"\n";
 
  932                $tlen = ($length / 4);
 
  934                for (
$i = 0; 
$i < $tlen; ++
$i) {
 
  935                        $v = unpack(
'Ni', substr(
$table, $offset, 4));
 
  939                $sum = unpack(
'Ni', pack(
'N', $sum));
 
  968                for (
$i = 0; 
$i < $numTables; ++
$i) {
 
  970                        $tag = substr($font, $offset, 4);
 
  981                $offset = 
$table[
'head'][
'offset'] + 12;
 
  988                $offset = 
$table[
'head'][
'offset'] + 50;
 
  992                $indexToLoc = array();
 
  993                $offset = 
$table[
'loca'][
'offset'];
 
  996                        $tot_num_glyphs = floor(
$table[
'loca'][
'length'] / 2); 
 
  997                        for (
$i = 0; 
$i < $tot_num_glyphs; ++
$i) {
 
 1003                        $tot_num_glyphs = (
$table[
'loca'][
'length'] / 4); 
 
 1004                        for (
$i = 0; 
$i < $tot_num_glyphs; ++
$i) {
 
 1010                $subsetglyphs = array(); 
 
 1011                $subsetglyphs[0] = 
true; 
 
 1012                $offset = 
$table[
'cmap'][
'offset'] + 2;
 
 1015                $encodingTables = array();
 
 1016                for (
$i = 0; 
$i < $numEncodingTables; ++
$i) {
 
 1024                foreach ($encodingTables as $enctable) {
 
 1026                        $offset = 
$table[
'cmap'][
'offset'] + $enctable[
'offset'];
 
 1032                                        for (
$c = 0; 
$c < 256; ++
$c) {
 
 1033                                                if (isset($subsetchars[
$c])) {
 
 1035                                                        $subsetglyphs[$g] = 
true;
 
 1044                                        for (
$i = 0; 
$i < 256; ++
$i) {
 
 1048                                                if ($numSubHeaders < $subHeaderKeys[
$i]) {
 
 1049                                                        $numSubHeaders = $subHeaderKeys[
$i];
 
 1055                                        $subHeaders = array();
 
 1056                                        $numGlyphIndexArray = 0;
 
 1057                                        for ($k = 0; $k < $numSubHeaders; ++$k) {
 
 1066                                                $subHeaders[$k][
'idRangeOffset'] -= (2 + (($numSubHeaders - $k - 1) * 8));
 
 1067                                                $subHeaders[$k][
'idRangeOffset'] /= 2;
 
 1068                                                $numGlyphIndexArray += $subHeaders[$k][
'entryCount'];
 
 1070                                        for ($k = 0; $k < $numGlyphIndexArray; ++$k) {
 
 1074                                        for (
$i = 0; 
$i < 256; ++
$i) {
 
 1075                                                $k = $subHeaderKeys[
$i];
 
 1079                                                        if (isset($subsetchars[
$c])) {
 
 1080                                                                $g = $glyphIndexArray[0];
 
 1081                                                                $subsetglyphs[$g] = 
true;
 
 1085                                                        $start_byte = $subHeaders[$k][
'firstCode'];
 
 1086                                                        $end_byte = $start_byte + $subHeaders[$k][
'entryCount'];
 
 1087                                                        for ($j = $start_byte; $j < $end_byte; ++$j) {
 
 1089                                                                $c = ((
$i << 8) + $j);
 
 1090                                                                if (isset($subsetchars[
$c])) {
 
 1091                                                                        $idRangeOffset = ($subHeaders[$k][
'idRangeOffset'] + $j - $subHeaders[$k][
'firstCode']);
 
 1092                                                                        $g = ($glyphIndexArray[$idRangeOffset] + $subHeaders[$k][
'idDelta']) % 65536;
 
 1096                                                                        $subsetglyphs[$g] = 
true;
 
 1110                                        $endCount = array(); 
 
 1111                                        for ($k = 0; $k < $segCount; ++$k) {
 
 1116                                        $startCount = array(); 
 
 1117                                        for ($k = 0; $k < $segCount; ++$k) {
 
 1122                                        for ($k = 0; $k < $segCount; ++$k) {
 
 1126                                        $idRangeOffset = array(); 
 
 1127                                        for ($k = 0; $k < $segCount; ++$k) {
 
 1131                                        $gidlen = (floor($length / 2) - 8 - (4 * $segCount));
 
 1132                                        $glyphIdArray = array(); 
 
 1133                                        for ($k = 0; $k < $gidlen; ++$k) {
 
 1137                                        for ($k = 0; $k < $segCount; ++$k) {
 
 1138                                                for (
$c = $startCount[$k]; 
$c <= $endCount[$k]; ++
$c) {
 
 1139                                                        if (isset($subsetchars[
$c])) {
 
 1140                                                                if ($idRangeOffset[$k] == 0) {
 
 1141                                                                        $g = ($idDelta[$k] + 
$c) % 65536;
 
 1143                                                                        $gid = (floor($idRangeOffset[$k] / 2) + (
$c - $startCount[$k]) - ($segCount - $k));
 
 1144                                                                        $g = ($glyphIdArray[$gid] + $idDelta[$k]) % 65536;
 
 1149                                                                $subsetglyphs[$g] = 
true;
 
 1161                                        for ($k = 0; $k < $entryCount; ++$k) {
 
 1162                                                $c = ($k + $firstCode);
 
 1163                                                if (isset($subsetchars[
$c])) {
 
 1165                                                        $subsetglyphs[$g] = 
true;
 
 1173                                        for ($k = 0; $k < 8192; ++$k) {
 
 1179                                        for (
$i = 0; 
$i < $nGroups; ++
$i) {
 
 1186                                                for ($k = $startCharCode; $k <= $endCharCode; ++$k) {
 
 1187                                                        $is32idx = floor(
$c / 8);
 
 1188                                                        if ((isset($is32[$is32idx])) AND (($is32[$is32idx] & (1 << (7 - (
$c % 8)))) == 0)) {
 
 1195                                                                $c = ((55232 + ($k >> 10)) << 10) + (0xDC00 + ($k & 0x3FF)) -56613888;
 
 1197                                                        if (isset($subsetchars[
$c])) {
 
 1198                                                                $subsetglyphs[$startGlyphID] = 
true;
 
 1211                                        for ($k = 0; $k < $numChars; ++$k) {
 
 1212                                                $c = ($k + $startCharCode);
 
 1213                                                if (isset($subsetchars[
$c])) {
 
 1215                                                        $subsetglyphs[$g] = 
true;
 
 1225                                        for ($k = 0; $k < $nGroups; ++$k) {
 
 1232                                                for (
$c = $startCharCode; 
$c <= $endCharCode; ++
$c) {
 
 1233                                                        if (isset($subsetchars[
$c])) {
 
 1234                                                                $subsetglyphs[$startGlyphCode] = 
true;
 
 1252                $new_sga = $subsetglyphs;
 
 1253                while (!empty($new_sga)) {
 
 1256                        foreach ($sga as 
$key => $val) {
 
 1257                                if (isset($indexToLoc[
$key])) {
 
 1258                                        $offset = (
$table[
'glyf'][
'offset'] + $indexToLoc[
$key]);
 
 1261                                        if ($numberOfContours < 0) { 
 
 1268                                                        if (!isset($subsetglyphs[$glyphIndex])) {
 
 1270                                                                $new_sga[$glyphIndex] = 
true;
 
 1280                                                        } elseif ($flags & 64) {
 
 1282                                                        } elseif ($flags & 128) {
 
 1285                                                } 
while ($flags & 32);
 
 1289                        $subsetglyphs += $new_sga;
 
 1292                ksort($subsetglyphs);
 
 1297                $glyf_offset = 
$table[
'glyf'][
'offset'];
 
 1298                for (
$i = 0; 
$i < $tot_num_glyphs; ++
$i) {
 
 1299                        if (isset($subsetglyphs[
$i])) {
 
 1300                                $length = ($indexToLoc[(
$i + 1)] - $indexToLoc[
$i]);
 
 1301                                $glyf .= substr($font, ($glyf_offset + $indexToLoc[
$i]), $length);
 
 1305                        if ($short_offset) {
 
 1306                                $loca .= pack(
'n', floor($offset / 2));
 
 1308                                $loca .= pack(
'N', $offset);
 
 1314                $table_names = array (
'head', 
'hhea', 
'hmtx', 
'maxp', 
'cvt ', 
'fpgm', 
'prep'); 
 
 1318                        if (in_array(
$tag, $table_names)) {
 
 1320                                if (
$tag == 
'head') {
 
 1328                                        $table[
$tag][
'data'] .= str_repeat(
"\x0", $pad);
 
 1339                $table[
'loca'][
'data'] = $loca;
 
 1340                $table[
'loca'][
'length'] = strlen($loca);
 
 1341                $pad = 4 - (
$table[
'loca'][
'length'] % 4);
 
 1344                        $table[
'loca'][
'length'] += $pad;
 
 1345                        $table[
'loca'][
'data'] .= str_repeat(
"\x0", $pad);
 
 1347                $table[
'loca'][
'offset'] = $offset;
 
 1348                $table[
'loca'][
'checkSum'] = self::_getTTFtableChecksum(
$table[
'loca'][
'data'], 
$table[
'loca'][
'length']);
 
 1349                $offset += 
$table[
'loca'][
'length'];
 
 1351                $table[
'glyf'][
'data'] = $glyf;
 
 1352                $table[
'glyf'][
'length'] = strlen($glyf);
 
 1353                $pad = 4 - (
$table[
'glyf'][
'length'] % 4);
 
 1356                        $table[
'glyf'][
'length'] += $pad;
 
 1357                        $table[
'glyf'][
'data'] .= str_repeat(
"\x0", $pad);
 
 1359                $table[
'glyf'][
'offset'] = $offset;
 
 1360                $table[
'glyf'][
'checkSum'] = self::_getTTFtableChecksum(
$table[
'glyf'][
'data'], 
$table[
'glyf'][
'length']);
 
 1363                $font .= pack(
'N', 0x10000); 
 
 1364                $numTables = count(
$table);
 
 1365                $font .= pack(
'n', $numTables); 
 
 1366                $entrySelector = floor(log($numTables, 2));
 
 1367                $searchRange = pow(2, $entrySelector) * 16;
 
 1368                $rangeShift = ($numTables * 16) - $searchRange;
 
 1369                $font .= pack(
'n', $searchRange); 
 
 1370                $font .= pack(
'n', $entrySelector); 
 
 1371                $font .= pack(
'n', $rangeShift); 
 
 1372                $offset = ($numTables * 16);
 
 1375                        $font .= pack(
'N', 
$data[
'checkSum']); 
 
 1376                        $font .= pack(
'N', (
$data[
'offset'] + $offset)); 
 
 1377                        $font .= pack(
'N', 
$data[
'length']); 
 
 1380                        $font .= 
$data[
'data'];
 
 1383                $checkSumAdjustment = 0xB1B0AFBA - self::_getTTFtableChecksum($font, strlen($font));
 
 1384                $font = substr($font, 0, 
$table[
'head'][
'offset'] + 8).pack(
'N', $checkSumAdjustment).substr($font, 
$table[
'head'][
'offset'] + 12);
 
 1405                foreach ($font[
'cw'] as $cid => $width) {
 
 1407                        if ($font[
'subset'] AND (!isset($font[
'subsetchars'][$cid]))) {
 
 1411                        if ($width != $font[
'dw']) {
 
 1412                                if ($cid == ($prevcid + 1)) {
 
 1414                                        if ($width == $prevwidth) {
 
 1415                                                if ($width == $range[$rangeid][0]) {
 
 1416                                                        $range[$rangeid][] = $width;
 
 1418                                                        array_pop($range[$rangeid]);
 
 1420                                                        $rangeid = $prevcid;
 
 1421                                                        $range[$rangeid] = array();
 
 1422                                                        $range[$rangeid][] = $prevwidth;
 
 1423                                                        $range[$rangeid][] = $width;
 
 1426                                                $range[$rangeid][
'interval'] = 
true;
 
 1431                                                        $range[$rangeid] = array();
 
 1432                                                        $range[$rangeid][] = $width;
 
 1434                                                        $range[$rangeid][] = $width;
 
 1441                                        $range[$rangeid] = array();
 
 1442                                        $range[$rangeid][] = $width;
 
 1446                                $prevwidth = $width;
 
 1453                foreach ($range as $k => $ws) {
 
 1455                        if (($k == $nextk) AND (!$prevint) AND ((!isset($ws[
'interval'])) OR ($cws < 4))) {
 
 1456                                if (isset($range[$k][
'interval'])) {
 
 1457                                        unset($range[$k][
'interval']);
 
 1459                                $range[$prevk] = array_merge($range[$prevk], $range[$k]);
 
 1465                        if (isset($ws[
'interval'])) {
 
 1471                                if (isset($range[$k][
'interval'])) {
 
 1472                                        unset($range[$k][
'interval']);
 
 1481                foreach ($range as $k => $ws) {
 
 1482                        if (count(array_count_values($ws)) == 1) {
 
 1484                                $w .= 
' '.$k.
' '.($k + count($ws) - 1).
' '.$ws[0];
 
 1487                                $w .= 
' '.$k.
' [ '.implode(
' ', $ws).
' ]';
 
 1490                return '/W ['.$w.
' ]';
 
 1507                if (($cid >= 0) AND ($cid <= 0xFFFF) AND ($gid >= 0)) {
 
 1508                        if ($gid > 0xFFFF) {
 
 1511                        $map[($cid * 2)] = chr($gid >> 8);
 
 1512                        $map[(($cid * 2) + 1)] = chr($gid & 0xFF);
 
 1523                if (!defined(
'K_PATH_FONTS') AND is_dir($fdir = realpath(dirname(__FILE__).
'/../fonts'))) {
 
 1524                        if (substr($fdir, -1) != 
'/') {
 
 1527                        define(
'K_PATH_FONTS', $fdir);
 
 1529                return defined(
'K_PATH_FONTS') ? K_PATH_FONTS : 
'';
 
 1546                if (($fontdir !== 
false) AND @file_exists($fontdir.$file)) {
 
 1547                        $fontfile = $fontdir.$file;
 
 1548                } elseif (@file_exists(self::_getfontpath().$file)) {
 
 1549                        $fontfile = self::_getfontpath().$file;
 
 1550                } elseif (@file_exists($file)) {
 
 1569                                $size = ($refsize - 4);
 
 1573                                $size = ($refsize - 3);
 
 1577                                $size = ($refsize - 2);
 
 1585                                $size = ($refsize + 2);
 
 1589                                $size = ($refsize + 4);
 
 1593                                $size = ($refsize + 6);
 
 1597                                $size = ($refsize - 3);
 
 1601                                $size = ($refsize + 3);
 
 1669                } elseif (
$c <= 0x7F) {
 
 1672                } elseif (
$c <= 0x7FF) {
 
 1674                        return chr(0xC0 | 
$c >> 6).chr(0x80 | 
$c & 0x3F);
 
 1675                } elseif (
$c <= 0xFFFF) {
 
 1677                        return chr(0xE0 | 
$c >> 12).chr(0x80 | 
$c >> 6 & 0x3F).chr(0x80 | 
$c & 0x3F);
 
 1678                } elseif (
$c <= 0x10FFFF) {
 
 1680                        return chr(0xF0 | 
$c >> 18).chr(0x80 | 
$c >> 12 & 0x3F).chr(0x80 | 
$c >> 6 & 0x3F).chr(0x80 | 
$c & 0x3F);
 
 1693                return self::unichr(
$c, 
true);
 
 1703                return self::unichr(
$c, 
false);
 
 1747                        $outstr .= 
"\xFE\xFF"; 
 
 1749                foreach ($unicode as $char) {
 
 1750                        if ($char == 0x200b) {
 
 1752                        } elseif ($char == 0xFFFD) {
 
 1753                                $outstr .= 
"\xFF\xFD"; 
 
 1754                        } elseif ($char < 0x10000) {
 
 1755                                $outstr .= chr($char >> 0x08);
 
 1756                                $outstr .= chr($char & 0xFF);
 
 1759                                $w1 = 0xD800 | ($char >> 0x0a);
 
 1760                                $w2 = 0xDC00 | ($char & 0x3FF);
 
 1761                                $outstr .= chr($w1 >> 0x08);
 
 1762                                $outstr .= chr($w1 & 0xFF);
 
 1763                                $outstr .= chr($w2 >> 0x08);
 
 1764                                $outstr .= chr($w2 & 0xFF);
 
 1780                        return array_map(array(
'TCPDF_FONTS', 
'unichrUnicode'), $ta);
 
 1782                return array_map(array(
'TCPDF_FONTS', 
'unichrASCII'), $ta);
 
 1795                if (strlen(
$start) == 0) {
 
 1798                if (strlen(
$end) == 0) {
 
 1799                        $end = count($strarr);
 
 1803                        $string .= self::unichr($strarr[
$i], $unicode);
 
 1818                if (strlen(
$start) == 0) {
 
 1821                if (strlen(
$end) == 0) {
 
 1822                        $end = count($uniarr);
 
 1826                        $string .= $uniarr[
$i];
 
 1841                foreach ($unicode as $char) {
 
 1847                        } elseif ($char == 0xFFFD) {
 
 1866                foreach ($unicode as $char) {
 
 1868                                $outstr .= chr($char);
 
 1872                        } elseif ($char == 0xFFFD) {
 
 1889                if (!isset(self::$cache_uniord[$uch])) {
 
 1890                        self::$cache_uniord[$uch] = self::getUniord($uch);
 
 1892                return self::$cache_uniord[$uch];
 
 1929                if (function_exists(
'mb_convert_encoding')) {
 
 1930                        list(, $char) = @unpack(
'N', mb_convert_encoding($uch, 
'UCS-4BE', 
'UTF-8'));
 
 1938                $length = strlen($uch);
 
 1939                for (
$i = 0; 
$i < $length; ++
$i) {
 
 1940                        $char = ord($uch[
$i]); 
 
 1941                        if ($countbytes == 0) { 
 
 1942                                if ($char <= 0x7F) {
 
 1944                                } elseif (($char >> 0x05) == 0x06) { 
 
 1945                                        $bytes[] = ($char - 0xC0) << 0x06;
 
 1948                                } elseif (($char >> 0x04) == 0x0E) { 
 
 1949                                        $bytes[] = ($char - 0xE0) << 0x0C;
 
 1952                                } elseif (($char >> 0x03) == 0x1E) { 
 
 1953                                        $bytes[] = ($char - 0xF0) << 0x12;
 
 1960                        } elseif (($char >> 0x06) == 0x02) { 
 
 1961                                $bytes[] = $char - 0x80;
 
 1963                                if ($countbytes == $numbytes) {
 
 1966                                        for ($j = 1; $j < $numbytes; ++$j) {
 
 1967                                                $char += ($bytes[$j] << (($numbytes - $j - 1) * 0x06));
 
 1969                                        if ((($char >= 0xD800) AND ($char <= 0xDFFF)) OR ($char >= 0x10FFFF)) {
 
 2001                        $carr = array_map(array(
'TCPDF_FONTS', 
'uniord'), $chars);
 
 2003                        $chars = str_split($str);
 
 2004                        $carr = array_map(
'ord', $chars);
 
 2006                $currentfont[
'subsetchars'] += array_fill_keys($carr, 
true);
 
 2019        public static function UTF8ToLatin1($str, $isunicode=
true, &$currentfont) {
 
 2020                $unicode = self::UTF8StringToArray($str, $isunicode, $currentfont); 
 
 2021                return self::UTF8ArrToLatin1($unicode);
 
 2035        public static function UTF8ToUTF16BE($str, $setbom=
false, $isunicode=
true, &$currentfont) {
 
 2039                $unicode = self::UTF8StringToArray($str, $isunicode, $currentfont); 
 
 2040                return self::arrUTF8ToUTF16BE($unicode, $setbom);
 
 2055        public static function utf8StrRev($str, $setbom=
false, $forcertl=
false, $isunicode=
true, &$currentfont) {
 
 2056                return self::utf8StrArrRev(self::UTF8StringToArray($str, $isunicode, $currentfont), $str, $setbom, $forcertl, $isunicode, $currentfont);
 
 2072        public static function utf8StrArrRev($arr, $str=
'', $setbom=
false, $forcertl=
false, $isunicode=
true, &$currentfont) {
 
 2073                return self::arrUTF8ToUTF16BE(self::utf8Bidi($arr, $str, $forcertl, $isunicode, $currentfont), $setbom);
 
 2088        public static function utf8Bidi($ta, $str=
'', $forcertl=
false, $isunicode=
true, &$currentfont) {
 
 2095                        $str = self::UTF8ArrSubString($ta, 
'', 
'', $isunicode);
 
 2109                $numchars = count($ta);
 
 2111                if ($forcertl == 
'R') {
 
 2113                } elseif ($forcertl == 
'L') {
 
 2118                        for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2123                                } elseif ((
$type == 
'AL') OR (
$type == 
'R')) {
 
 2134                $remember = array();
 
 2136                $sor = $pel % 2 ? 
'R' : 
'L';
 
 2140                $chardata = Array();
 
 2144                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2149                                $next_level = $cel + ($cel % 2) + 1;
 
 2150                                if ($next_level < 62) {
 
 2155                                        $eor = $cel % 2 ? 
'R' : 
'L';
 
 2161                                $next_level = $cel + 2 - ($cel % 2);
 
 2162                                if ( $next_level < 62 ) {
 
 2167                                        $eor = $cel % 2 ? 
'R' : 
'L';
 
 2173                                $next_level = $cel + ($cel % 2) + 1;
 
 2174                                if ($next_level < 62) {
 
 2179                                        $eor = $cel % 2 ? 
'R' : 
'L';
 
 2185                                $next_level = $cel + 2 - ($cel % 2);
 
 2186                                if ( $next_level < 62 ) {
 
 2191                                        $eor = $cel % 2 ? 
'R' : 
'L';
 
 2195                                if (count($remember)) {
 
 2196                                        $last = count($remember ) - 1;
 
 2201                                                $match = array_pop($remember);
 
 2202                                                $cel = $match[
'cel'];
 
 2203                                                $dos = $match[
'dos'];
 
 2205                                                $eor = ($cel > $match[
'cel'] ? $cel : $match[
'cel']) % 2 ? 
'R' : 
'L';
 
 2226                                $chardata[] = array(
'char' => $ta[
$i], 
'level' => $cel, 
'type' => $chardir, 
'sor' => $sor, 
'eor' => $eor);
 
 2237                $numchars = count($chardata);
 
 2242                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2243                        if ($chardata[
$i][
'type'] == 
'NSM') {
 
 2245                                        $chardata[
$i][
'type'] = $chardata[
$i][
'sor'];
 
 2247                                        $chardata[
$i][
'type'] = $chardata[(
$i-1)][
'type'];
 
 2250                        if ($chardata[
$i][
'level'] != $prevlevel) {
 
 2255                        $prevlevel = $chardata[
$i][
'level'];
 
 2261                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2262                        if ($chardata[
$i][
'char'] == 
'EN') {
 
 2263                                for ($j=$levcount; $j >= 0; $j--) {
 
 2264                                        if ($chardata[$j][
'type'] == 
'AL') {
 
 2265                                                $chardata[
$i][
'type'] = 
'AN';
 
 2266                                        } elseif (($chardata[$j][
'type'] == 
'L') OR ($chardata[$j][
'type'] == 
'R')) {
 
 2271                        if ($chardata[
$i][
'level'] != $prevlevel) {
 
 2276                        $prevlevel = $chardata[
$i][
'level'];
 
 2280                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2281                        if ($chardata[
$i][
'type'] == 
'AL') {
 
 2282                                $chardata[
$i][
'type'] = 
'R';
 
 2289                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2290                        if (($levcount > 0) AND ((
$i+1) < $numchars) AND ($chardata[(
$i+1)][
'level'] == $prevlevel)) {
 
 2291                                if (($chardata[
$i][
'type'] == 
'ES') AND ($chardata[(
$i-1)][
'type'] == 
'EN') AND ($chardata[(
$i+1)][
'type'] == 
'EN')) {
 
 2292                                        $chardata[
$i][
'type'] = 
'EN';
 
 2293                                } elseif (($chardata[
$i][
'type'] == 
'CS') AND ($chardata[(
$i-1)][
'type'] == 
'EN') AND ($chardata[(
$i+1)][
'type'] == 
'EN')) {
 
 2294                                        $chardata[
$i][
'type'] = 
'EN';
 
 2295                                } elseif (($chardata[
$i][
'type'] == 
'CS') AND ($chardata[(
$i-1)][
'type'] == 
'AN') AND ($chardata[(
$i+1)][
'type'] == 
'AN')) {
 
 2296                                        $chardata[
$i][
'type'] = 
'AN';
 
 2299                        if ($chardata[
$i][
'level'] != $prevlevel) {
 
 2304                        $prevlevel = $chardata[
$i][
'level'];
 
 2310                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2311                        if ($chardata[
$i][
'type'] == 
'ET') {
 
 2312                                if (($levcount > 0) AND ($chardata[(
$i-1)][
'type'] == 
'EN')) {
 
 2313                                        $chardata[
$i][
'type'] = 
'EN';
 
 2316                                        while (($j < $numchars) AND ($chardata[$j][
'level'] == $prevlevel)) {
 
 2317                                                if ($chardata[$j][
'type'] == 
'EN') {
 
 2318                                                        $chardata[
$i][
'type'] = 
'EN';
 
 2320                                                } elseif ($chardata[$j][
'type'] != 
'ET') {
 
 2327                        if ($chardata[
$i][
'level'] != $prevlevel) {
 
 2332                        $prevlevel = $chardata[
$i][
'level'];
 
 2338                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2339                        if (($chardata[
$i][
'type'] == 
'ET') OR ($chardata[
$i][
'type'] == 
'ES') OR ($chardata[
$i][
'type'] == 
'CS')) {
 
 2340                                $chardata[
$i][
'type'] = 
'ON';
 
 2342                        if ($chardata[
$i][
'level'] != $prevlevel) {
 
 2347                        $prevlevel = $chardata[
$i][
'level'];
 
 2353                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2354                        if ($chardata[
$i][
'char'] == 
'EN') {
 
 2355                                for ($j=$levcount; $j >= 0; $j--) {
 
 2356                                        if ($chardata[$j][
'type'] == 
'L') {
 
 2357                                                $chardata[
$i][
'type'] = 
'L';
 
 2358                                        } elseif ($chardata[$j][
'type'] == 
'R') {
 
 2363                        if ($chardata[
$i][
'level'] != $prevlevel) {
 
 2368                        $prevlevel = $chardata[
$i][
'level'];
 
 2374                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2375                        if (($levcount > 0) AND ((
$i+1) < $numchars) AND ($chardata[(
$i+1)][
'level'] == $prevlevel)) {
 
 2376                                if (($chardata[
$i][
'type'] == 
'N') AND ($chardata[(
$i-1)][
'type'] == 
'L') AND ($chardata[(
$i+1)][
'type'] == 
'L')) {
 
 2377                                        $chardata[
$i][
'type'] = 
'L';
 
 2378                                } elseif (($chardata[
$i][
'type'] == 
'N') AND
 
 2379                                 (($chardata[(
$i-1)][
'type'] == 
'R') OR ($chardata[(
$i-1)][
'type'] == 
'EN') OR ($chardata[(
$i-1)][
'type'] == 
'AN')) AND
 
 2380                                 (($chardata[(
$i+1)][
'type'] == 
'R') OR ($chardata[(
$i+1)][
'type'] == 
'EN') OR ($chardata[(
$i+1)][
'type'] == 
'AN'))) {
 
 2381                                        $chardata[
$i][
'type'] = 
'R';
 
 2382                                } elseif ($chardata[
$i][
'type'] == 
'N') {
 
 2384                                        $chardata[
$i][
'type'] = $chardata[
$i][
'sor'];
 
 2386                        } elseif (($levcount == 0) AND ((
$i+1) < $numchars) AND ($chardata[(
$i+1)][
'level'] == $prevlevel)) {
 
 2388                                if (($chardata[
$i][
'type'] == 
'N') AND ($chardata[
$i][
'sor'] == 
'L') AND ($chardata[(
$i+1)][
'type'] == 
'L')) {
 
 2389                                        $chardata[
$i][
'type'] = 
'L';
 
 2390                                } elseif (($chardata[
$i][
'type'] == 
'N') AND
 
 2391                                 (($chardata[
$i][
'sor'] == 
'R') OR ($chardata[
$i][
'sor'] == 
'EN') OR ($chardata[
$i][
'sor'] == 
'AN')) AND
 
 2392                                 (($chardata[(
$i+1)][
'type'] == 
'R') OR ($chardata[(
$i+1)][
'type'] == 
'EN') OR ($chardata[(
$i+1)][
'type'] == 
'AN'))) {
 
 2393                                        $chardata[
$i][
'type'] = 
'R';
 
 2394                                } elseif ($chardata[
$i][
'type'] == 
'N') {
 
 2396                                        $chardata[
$i][
'type'] = $chardata[
$i][
'sor'];
 
 2398                        } elseif (($levcount > 0) AND (((
$i+1) == $numchars) OR ((
$i+1) < $numchars) AND ($chardata[(
$i+1)][
'level'] != $prevlevel))) {
 
 2400                                if (($chardata[
$i][
'type'] == 
'N') AND ($chardata[(
$i-1)][
'type'] == 
'L') AND ($chardata[
$i][
'eor'] == 
'L')) {
 
 2401                                        $chardata[
$i][
'type'] = 
'L';
 
 2402                                } elseif (($chardata[
$i][
'type'] == 
'N') AND
 
 2403                                 (($chardata[(
$i-1)][
'type'] == 
'R') OR ($chardata[(
$i-1)][
'type'] == 
'EN') OR ($chardata[(
$i-1)][
'type'] == 
'AN')) AND
 
 2404                                 (($chardata[
$i][
'eor'] == 
'R') OR ($chardata[
$i][
'eor'] == 
'EN') OR ($chardata[
$i][
'eor'] == 
'AN'))) {
 
 2405                                        $chardata[
$i][
'type'] = 
'R';
 
 2406                                } elseif ($chardata[
$i][
'type'] == 
'N') {
 
 2408                                        $chardata[
$i][
'type'] = $chardata[
$i][
'sor'];
 
 2410                        } elseif ($chardata[
$i][
'type'] == 
'N') {
 
 2412                                $chardata[
$i][
'type'] = $chardata[
$i][
'sor'];
 
 2414                        if ($chardata[
$i][
'level'] != $prevlevel) {
 
 2419                        $prevlevel = $chardata[
$i][
'level'];
 
 2424                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2425                        $odd = $chardata[
$i][
'level'] % 2;
 
 2427                                if (($chardata[
$i][
'type'] == 
'L') OR ($chardata[
$i][
'type'] == 
'AN') OR ($chardata[
$i][
'type'] == 
'EN')) {
 
 2428                                        $chardata[
$i][
'level'] += 1;
 
 2431                                if ($chardata[
$i][
'type'] == 
'R') {
 
 2432                                        $chardata[
$i][
'level'] += 1;
 
 2433                                } elseif (($chardata[
$i][
'type'] == 
'AN') OR ($chardata[
$i][
'type'] == 
'EN')) {
 
 2434                                        $chardata[
$i][
'level'] += 2;
 
 2437                        $maxlevel = max($chardata[
$i][
'level'],$maxlevel);
 
 2445                for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2446                        if (($chardata[
$i][
'type'] == 
'B') OR ($chardata[
$i][
'type'] == 
'S')) {
 
 2447                                $chardata[
$i][
'level'] = $pel;
 
 2448                        } elseif ($chardata[
$i][
'type'] == 
'WS') {
 
 2450                                while ($j < $numchars) {
 
 2451                                        if ((($chardata[$j][
'type'] == 
'B') OR ($chardata[$j][
'type'] == 
'S')) OR
 
 2452                                                (($j == ($numchars-1)) AND ($chardata[$j][
'type'] == 
'WS'))) {
 
 2453                                                $chardata[
$i][
'level'] = $pel;
 
 2455                                        } elseif ($chardata[$j][
'type'] != 
'WS') {
 
 2466                        $endedletter = array(1569,1570,1571,1572,1573,1575,1577,1583,1584,1585,1586,1608,1688);
 
 2467                        $alfletter = array(1570,1571,1573,1575);
 
 2468                        $chardata2 = $chardata;
 
 2472                        for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2474                                        $charAL[
$x] = $chardata[
$i];
 
 2475                                        $charAL[
$x][
'i'] = 
$i;
 
 2476                                        $chardata[
$i][
'x'] = 
$x;
 
 2481                        for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2482                                $thischar = $chardata[
$i];
 
 2484                                        $prevchar = $chardata[(
$i-1)];
 
 2488                                if ((
$i+1) < $numchars) {
 
 2489                                        $nextchar = $chardata[(
$i+1)];
 
 2494                                        $x = $thischar[
'x'];
 
 2496                                                $prevchar = $charAL[(
$x-1)];
 
 2500                                        if ((
$x+1) < $numAL) {
 
 2501                                                $nextchar = $charAL[(
$x+1)];
 
 2506                                        if (($prevchar !== 
false) AND ($prevchar[
'char'] == 1604) AND (in_array($thischar[
'char'], $alfletter))) {
 
 2510                                                        $prevchar = $charAL[(
$x-2)];
 
 2518                                        if (($prevchar !== 
false) AND ($nextchar !== 
false) AND
 
 2521                                                ($prevchar[
'type'] == $thischar[
'type']) AND
 
 2522                                                ($nextchar[
'type'] == $thischar[
'type']) AND
 
 2523                                                ($nextchar[
'char'] != 1567)) {
 
 2524                                                if (in_array($prevchar[
'char'], $endedletter)) {
 
 2525                                                        if (isset($arabicarr[$thischar[
'char']][2])) {
 
 2527                                                                $chardata2[
$i][
'char'] = $arabicarr[$thischar[
'char']][2];
 
 2530                                                        if (isset($arabicarr[$thischar[
'char']][3])) {
 
 2532                                                                $chardata2[
$i][
'char'] = $arabicarr[$thischar[
'char']][3];
 
 2535                                        } elseif (($nextchar !== 
false) AND
 
 2537                                                ($nextchar[
'type'] == $thischar[
'type']) AND
 
 2538                                                ($nextchar[
'char'] != 1567)) {
 
 2539                                                if (isset($arabicarr[$chardata[
$i][
'char']][2])) {
 
 2541                                                        $chardata2[
$i][
'char'] = $arabicarr[$thischar[
'char']][2];
 
 2543                                        } elseif ((($prevchar !== 
false) AND
 
 2545                                                ($prevchar[
'type'] == $thischar[
'type'])) OR
 
 2546                                                (($nextchar !== 
false) AND ($nextchar[
'char'] == 1567))) {
 
 2548                                                if ((
$i > 1) AND ($thischar[
'char'] == 1607) AND
 
 2549                                                        ($chardata[
$i-1][
'char'] == 1604) AND
 
 2550                                                        ($chardata[
$i-2][
'char'] == 1604)) {
 
 2553                                                        $chardata2[
$i-2][
'char'] = 
false;
 
 2554                                                        $chardata2[
$i-1][
'char'] = 
false;
 
 2555                                                        $chardata2[
$i][
'char'] = 65010;
 
 2557                                                        if (($prevchar !== 
false) AND in_array($prevchar[
'char'], $endedletter)) {
 
 2558                                                                if (isset($arabicarr[$thischar[
'char']][0])) {
 
 2560                                                                        $chardata2[
$i][
'char'] = $arabicarr[$thischar[
'char']][0];
 
 2563                                                                if (isset($arabicarr[$thischar[
'char']][1])) {
 
 2565                                                                        $chardata2[
$i][
'char'] = $arabicarr[$thischar[
'char']][1];
 
 2569                                        } elseif (isset($arabicarr[$thischar[
'char']][0])) {
 
 2571                                                $chardata2[
$i][
'char'] = $arabicarr[$thischar[
'char']][0];
 
 2576                                                $chardata2[($charAL[(
$x-1)][
'i'])][
'char'] = 
false;
 
 2584                        for (
$i = 0; 
$i < ($numchars-1); ++
$i) {
 
 2588                                                $chardata2[
$i][
'char'] = 
false;
 
 2594                        foreach ($chardata2 as 
$key => $value) {
 
 2595                                if ($value[
'char'] === 
false) {
 
 2596                                        unset($chardata2[
$key]);
 
 2599                        $chardata = array_values($chardata2);
 
 2600                        $numchars = count($chardata);
 
 2608                for ($j=$maxlevel; $j > 0; $j--) {
 
 2609                        $ordarray = Array();
 
 2612                        for (
$i=0; 
$i < $numchars; ++
$i) {
 
 2613                                if ($chardata[
$i][
'level'] >= $j) {
 
 2619                                        $revarr[] = $chardata[
$i];
 
 2622                                                $revarr = array_reverse($revarr);
 
 2623                                                $ordarray = array_merge($ordarray, $revarr);
 
 2627                                        $ordarray[] = $chardata[
$i];
 
 2631                                $revarr = array_reverse($revarr);
 
 2632                                $ordarray = array_merge($ordarray, $revarr);
 
 2634                        $chardata = $ordarray;
 
 2636                $ordarray = array();
 
 2637                foreach ($chardata as $cd) {
 
 2638                        $ordarray[] = $cd[
'char'];
 
 2640                        $currentfont[
'subsetchars'][$cd[
'char']] = 
true;
 
An exception for terminatinating execution or to throw for unit testing.
Font methods for TCPDF library.
static $cache_uniord
Static cache used for speed up uniord performances.
static uniord($uch)
Converts UTF-8 character to integer value.
static utf8StrRev($str, $setbom=false, $forcertl=false, $isunicode=true, &$currentfont)
Reverse the RLT substrings using the Bidirectional Algorithm (http://unicode.org/reports/tr9/).
static _putfontwidths($font, $cidoffset=0)
Outputs font widths.
static UTF8ArrSubString($strarr, $start='', $end='', $unicode=true)
Extract a slice of the $strarr array and return it as string.
static UniArrSubString($uniarr, $start='', $end='')
Extract a slice of the $uniarr array and return it as string.
static getFontFullPath($file, $fontdir=false)
Return font full path.
static UTF8ArrToLatin1Arr($unicode)
Converts UTF-8 characters array to array of Latin1 characters array
static utf8Bidi($ta, $str='', $forcertl=false, $isunicode=true, &$currentfont)
Reverse the RLT substrings using the Bidirectional Algorithm (http://unicode.org/reports/tr9/).
static UTF8ToLatin1($str, $isunicode=true, &$currentfont)
Converts UTF-8 strings to Latin1 when using the standard 14 core fonts.
static unichr($c, $unicode=true)
Returns the unicode caracter specified by the value.
static _getfontpath()
Return fonts path.
static UTF8StringToArray($str, $isunicode=true, &$currentfont)
Converts UTF-8 strings to codepoints array.
static addTTFfont($fontfile, $fonttype='', $enc='', $flags=32, $outpath='', $platid=3, $encid=1, $addcbbox=false, $link=false)
Convert and add the selected TrueType or Type1 font to the fonts folder (that must be writeable).
static UTF8ArrToLatin1($unicode)
Converts UTF-8 characters array to array of Latin1 string
static arrUTF8ToUTF16BE($unicode, $setbom=false)
Converts array of UTF-8 characters to UTF16-BE string.
static updateCIDtoGIDmap($map, $cid, $gid)
Update the CIDToGIDMap string with a new value.
static unichrUnicode($c)
Returns the unicode caracter specified by UTF-8 value.
static _getTTFtableChecksum($table, $length)
Returs the checksum of a TTF table.
static utf8StrArrRev($arr, $str='', $setbom=false, $forcertl=false, $isunicode=true, &$currentfont)
Reverse the RLT substrings array using the Bidirectional Algorithm (http://unicode....
static getFontRefSize($size, $refsize=12)
Get a reference font size.
static UTF8ToUTF16BE($str, $setbom=false, $isunicode=true, &$currentfont)
Converts UTF-8 strings to UTF16-BE.
static getUniord($uch)
Converts UTF-8 character to integer value.
static unichrASCII($c)
Returns the unicode caracter specified by ASCII value.
static UTF8ArrayToUniArray($ta, $isunicode=true)
Convert an array of UTF8 values to array of unicode characters.
static _getTrueTypeFontSubset($font, $subsetchars)
Returns a subset of the TrueType font data without the unused glyphs.
static $uni_LRO
Unicode code for Left-to-Right Override.
static $uni_type
Array of Unicode types.
static $uni_PDF
Unicode code for Pop Directional Format.
static $uni_diacritics
Array of character substitutions for sequences of two diacritics symbols.
static $uni_RLE
Unicode code for Right-to-Left Embedding.
static $encmap
Array of Encoding Maps.
static $uni_mirror
Mirror unicode characters.
static $uni_RLO
Unicode code for Right-to-Left Override.
static $uni_arabicsubst
Arabic shape substitutions: char code => (isolated, final, initial, medial).
static $uni_LRE
Unicode code for Left-to-Right Embedding.
static $uni_RE_PATTERN_ARABIC
Pattern to test Arabic strings using regular expressions.
static $uni_utf8tolatin
Array of character substitutions from UTF-8 Unicode to Latin1.
static $uni_RE_PATTERN_RTL
Pattern to test RTL (Righ-To-Left) strings using regular expressions.
static $uni_laa_array
Arabic laa letter: (char code => isolated, final, initial, medial).
static fopenLocal($filename, $mode)
Wrapper to use fopen only with local files.
static _getFWORD($str, $offset)
Get FWORD from string (Big Endian 16-bit signed integer).
static _getSHORT($str, $offset)
Get SHORT from string (Big Endian 16-bit signed integer).
static pregSplit($pattern, $modifiers, $subject, $limit=NULL, $flags=NULL)
Split string by a regular expression.
static empty_string($str)
Determine whether a string is empty.
static _getBYTE($str, $offset)
Get BYTE from string (8-bit unsigned integer).
static _getUSHORT($str, $offset)
Get USHORT from string (Big Endian 16-bit unsigned integer).
static _getUFWORD($str, $offset)
Get UFWORD from string (Big Endian 16-bit unsigned integer).
static _getULONG($str, $offset)
Get ULONG from string (Big Endian 32-bit unsigned integer).
static _getFIXED($str, $offset)
Get FIXED from string (32-bit signed fixed-point number (16.16).
if(function_exists( 'posix_getuid') &&posix_getuid()===0) if(!array_key_exists('t', $options)) $tag
if(empty($password)) $table