[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/tcpdf/fonts/utils/ -> makefont.php (source)

   1  <?php
   2  //============================================================+
   3  // File name   : makefont.php
   4  // Begin       : 2004-12-31
   5  // Last Update : 2008-11-24
   6  // Version     : 1.2.002
   7  // License     : GNU LGPL (http://www.gnu.org/copyleft/lesser.html)
   8  //     ----------------------------------------------------------------------------
   9  //     Copyright (C) 2008  Nicola Asuni - Tecnick.com S.r.l.
  10  //     
  11  //     This program is free software: you can redistribute it and/or modify
  12  //     it under the terms of the GNU Lesser General Public License as published by
  13  //     the Free Software Foundation, either version 2.1 of the License, or
  14  //     (at your option) any later version.
  15  //     
  16  //     This program is distributed in the hope that it will be useful,
  17  //     but WITHOUT ANY WARRANTY; without even the implied warranty of
  18  //     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19  //     GNU Lesser General Public License for more details.
  20  //     
  21  //     You should have received a copy of the GNU Lesser General Public License
  22  //     along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23  //     
  24  //     See LICENSE.TXT file for more information.
  25  //  ----------------------------------------------------------------------------
  26  //
  27  // Description : Utility to generate font definition files fot TCPDF
  28  //
  29  // Author: Nicola Asuni, Olivier Plathey, Steven Wittens
  30  //
  31  // (c) Copyright:
  32  //               Nicola Asuni
  33  //               Tecnick.com S.r.l.
  34  //               Via della Pace, 11
  35  //               09044 Quartucciu (CA)
  36  //               ITALY
  37  //               www.tecnick.com
  38  //               [email protected]
  39  //============================================================+
  40  
  41  /**
  42   * Utility to generate font definition files fot TCPDF.
  43   * @author Nicola Asuni, Olivier Plathey, Steven Wittens
  44   * @copyright 2004-2008 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - [email protected]
  45   * @package com.tecnick.tcpdf
  46   * @link http://www.tcpdf.org
  47   * @license http://www.gnu.org/copyleft/lesser.html LGPL
  48  */
  49  
  50  /**
  51   * 
  52   * @param string $fontfile path to font file (TTF, OTF or PFB).
  53   * @param string $fmfile font metrics file (UFM or AFM).
  54   * @param boolean $embedded Set to false to not embed the font, true otherwise (default).
  55   * @param string $enc Name of the encoding table to use. Omit this parameter for TrueType Unicode, OpenType Unicode and symbolic fonts like Symbol or ZapfDingBats.
  56   * @param array $patch Optional modification of the encoding
  57   */
  58  function MakeFont($fontfile, $fmfile, $embedded=true, $enc="cp1252", $patch=array()) {
  59      //Generate a font definition file
  60      set_magic_quotes_runtime(0);
  61      ini_set('auto_detect_line_endings','1');
  62      if (!file_exists($fontfile)) {
  63          die('Error: file not found: '.$fontfile);
  64      }
  65      if (!file_exists($fmfile)) {
  66          die('Error: file not found: '.$fmfile);
  67      }
  68      $cidtogidmap = '';
  69      $map = array();
  70      $diff='';
  71      $ffext = strtolower(substr($fontfile,-3));
  72      $fmext = strtolower(substr($fmfile,-3));
  73      if ($fmext == 'afm') {
  74          if (($ffext == 'ttf') OR ($ffext == 'otf')) {
  75              $type = 'TrueType';
  76          } elseif ($ffext == 'pfb') {
  77              $type = 'Type1';
  78          } else {
  79              die('Error: unrecognized font file extension: '.$ffext);
  80          }
  81          if ($enc) {
  82              $map = ReadMap($enc);
  83              foreach ($patch as $cc => $gn) {
  84                  $map[$cc] = $gn;
  85              }
  86          }
  87          $fm = ReadAFM($fmfile, $map);
  88          if ($enc) {
  89              $diff = MakeFontEncoding($map);
  90          }
  91          $fd = MakeFontDescriptor($fm, empty($map));
  92      } elseif ($fmext == 'ufm') {
  93          $enc = "";
  94          if (($ffext == 'ttf') OR ($ffext == 'otf')) {
  95              $type = 'TrueTypeUnicode';
  96          } else {
  97              die('Error: not a TrueType font: '.$ffext);
  98          }
  99          $fm = ReadUFM($fmfile, $cidtogidmap);
 100          $fd = MakeFontDescriptor($fm, false);
 101      }
 102      
 103      //Start generation
 104      $s = '<?php'."\n";
 105      $s .= '$type=\''.$type."';\n";
 106      $s .= '$name=\''.$fm['FontName']."';\n";
 107      $s .= '$desc='.$fd.";\n";
 108      if (!isset($fm['UnderlinePosition'])) {
 109          $fm['UnderlinePosition'] = -100;
 110      }
 111      if (!isset($fm['UnderlineThickness'])) {
 112          $fm['UnderlineThickness'] = 50;
 113      }
 114      $s .= '$up='.$fm['UnderlinePosition'].";\n";
 115      $s .= '$ut='.$fm['UnderlineThickness'].";\n";
 116      $w = MakeWidthArray($fm);
 117      $s .= '$cw='.$w.";\n";
 118      $s .= '$enc=\''.$enc."';\n";
 119      $s .= '$diff=\''.$diff."';\n";
 120      $basename = substr(basename($fmfile),0,-4);
 121      if ($embedded) {
 122          //Embedded font
 123          if (($type == 'TrueType') OR ($type == 'TrueTypeUnicode')) {
 124              CheckTTF($fontfile);
 125          }
 126          $f = fopen($fontfile,'rb');
 127          if (!$f) {
 128              die('Error: Unable to open '.$fontfile);
 129          }
 130          $file = fread($f,filesize($fontfile));
 131          fclose($f);
 132          if ($type == 'Type1') {
 133              //Find first two sections and discard third one
 134              $header = (ord($file{0}) == 128);
 135              if ($header) {
 136                  //Strip first binary header
 137                  $file = substr($file, 6);
 138              }
 139              $pos = strpos($file, 'eexec');
 140              if (!$pos) {
 141                  die('Error: font file does not seem to be valid Type1');
 142              }
 143              $size1 = $pos+6;
 144              if ($header AND (ord($file{$size1}) == 128)) {
 145                  //Strip second binary header
 146                  $file = substr($file, 0, $size1).substr($file, $size1+6);
 147              }
 148              $pos = strpos($file, '00000000');
 149              if (!$pos) {
 150                  die('Error: font file does not seem to be valid Type1');
 151              }
 152              $size2 = $pos - $size1;
 153              $file = substr($file, 0, $size1+$size2);
 154          }
 155          if (function_exists('gzcompress')) {
 156              $cmp = $basename.'.z';
 157              SaveToFile($cmp, gzcompress($file), 'b');
 158              $s .= '$file=\''.$cmp."';\n";
 159              print "Font file compressed (".$cmp.")\n";
 160              if (!empty($cidtogidmap)) {
 161                  $cmp = $basename.'.ctg.z';
 162                  SaveToFile($cmp, gzcompress($cidtogidmap), 'b');
 163                  print "CIDToGIDMap created and compressed (".$cmp.")\n";
 164                  $s .= '$ctg=\''.$cmp."';\n";
 165              }
 166          } else {
 167              $s .= '$file=\''.basename($fontfile)."';\n";
 168              print "Notice: font file could not be compressed (zlib extension not available)\n";
 169              if (!empty($cidtogidmap)) {
 170                  $cmp = $basename.'.ctg';
 171                  $f = fopen($cmp, 'wb');
 172                  fwrite($f, $cidtogidmap);
 173                  fclose($f);
 174                  print "CIDToGIDMap created (".$cmp.")\n";
 175                  $s .= '$ctg=\''.$cmp."';\n";
 176              }
 177          }
 178          if($type == 'Type1') {
 179              $s .= '$size1='.$size1.";\n";
 180              $s .= '$size2='.$size2.";\n";
 181          } else {
 182              $s.='$originalsize='.filesize($fontfile).";\n";
 183          }
 184      } else {
 185          //Not embedded font
 186          $s .= '$file='."'';\n";
 187      }
 188      $s .= "?>";
 189      SaveToFile($basename.'.php',$s);
 190      print "Font definition file generated (".$basename.".php)\n";
 191  }
 192  
 193  /**
 194   * Read the specified encoding map.
 195   * @param string $enc map name (see /enc/ folder for valid names).
 196   */
 197  function ReadMap($enc) {
 198      //Read a map file
 199      $file = dirname(__FILE__).'/enc/'.strtolower($enc).'.map';
 200      $a = file($file);
 201      if (empty($a)) {
 202          die('Error: encoding not found: '.$enc);
 203      }
 204      $cc2gn = array();
 205      foreach ($a as $l) {
 206          if ($l{0} == '!') {
 207              $e = preg_split('/[ \\t]+/',rtrim($l));
 208              $cc = hexdec(substr($e[0],1));
 209              $gn = $e[2];
 210              $cc2gn[$cc] = $gn;
 211          }
 212      }
 213      for($i=0; $i <= 255; $i++) {
 214          if(!isset($cc2gn[$i])) {
 215              $cc2gn[$i] = '.notdef';
 216          }
 217      }
 218      return $cc2gn;
 219  }
 220  
 221  /**
 222   * Read UFM file
 223   */
 224  function ReadUFM($file, &$cidtogidmap) {
 225      //Prepare empty CIDToGIDMap
 226      $cidtogidmap = str_pad('', 256*256*2, "\x00");
 227      //Read a font metric file
 228      $a = file($file);
 229      if (empty($a)) {
 230          die('File not found');
 231      }
 232      $widths = array();
 233      $fm = array();
 234      foreach($a as $l) {
 235          $e = explode(' ',chop($l));
 236          if(count($e) < 2) {
 237              continue;
 238          }
 239          $code = $e[0];
 240          $param = $e[1];
 241          if($code == 'U') {
 242              // U 827 ; WX 0 ; N squaresubnosp ; G 675 ;
 243              //Character metrics
 244              $cc = (int)$e[1];
 245              if ($cc != -1) {
 246              $gn = $e[7];
 247              $w = $e[4];
 248              $glyph = $e[10];
 249              $widths[$cc] = $w;
 250              if($cc == ord('X')) {
 251                  $fm['CapXHeight'] = $e[13];
 252              }
 253              // Set GID
 254              if ($cc >= 0 && $cc < 0xFFFF && $glyph) {
 255                  $cidtogidmap{$cc*2} = chr($glyph >> 8);
 256                  $cidtogidmap{$cc*2 + 1} = chr($glyph & 0xFF);
 257              }
 258              }
 259              if(($gn == '.notdef') AND (!isset($fm['MissingWidth']))) {
 260                  $fm['MissingWidth'] = $w;
 261              }
 262          } elseif($code=='FontName') {
 263              $fm['FontName']=$param;
 264          } elseif($code=='Weight') {
 265              $fm['Weight']=$param;
 266          } elseif($code=='ItalicAngle') {
 267              $fm['ItalicAngle']=(double)$param;
 268          } elseif($code=='Ascender') {
 269              $fm['Ascender']=(int)$param;
 270          } elseif($code=='Descender') {
 271              $fm['Descender']=(int)$param;
 272          } elseif($code=='UnderlineThickness') {
 273              $fm['UnderlineThickness']=(int)$param;
 274          } elseif($code=='UnderlinePosition') {
 275              $fm['UnderlinePosition']=(int)$param;
 276          } elseif($code=='IsFixedPitch') {
 277              $fm['IsFixedPitch']=($param=='true');
 278          } elseif($code=='FontBBox') {
 279              $fm['FontBBox']=array($e[1],$e[2],$e[3],$e[4]);
 280          } elseif($code=='CapHeight') {
 281              $fm['CapHeight']=(int)$param;
 282          } elseif($code=='StdVW') {
 283              $fm['StdVW']=(int)$param;
 284          }
 285      }
 286      if(!isset($fm['MissingWidth'])) {
 287          $fm['MissingWidth'] = 600;
 288      }
 289      if(!isset($fm['FontName'])) {
 290          die('FontName not found');
 291      }
 292      $fm['Widths'] = $widths;
 293      return $fm;
 294  }
 295  
 296  /**
 297   * Read AFM file
 298   */
 299  function ReadAFM($file,&$map) {
 300      //Read a font metric file
 301      $a = file($file);
 302      if(empty($a)) {
 303          die('File not found');
 304      }
 305      $widths = array();
 306      $fm = array();
 307      $fix = array('Edot'=>'Edotaccent','edot'=>'edotaccent','Idot'=>'Idotaccent','Zdot'=>'Zdotaccent','zdot'=>'zdotaccent',
 308          'Odblacute'=>'Ohungarumlaut','odblacute'=>'ohungarumlaut','Udblacute'=>'Uhungarumlaut','udblacute'=>'uhungarumlaut',
 309          'Gcedilla'=>'Gcommaaccent','gcedilla'=>'gcommaaccent','Kcedilla'=>'Kcommaaccent','kcedilla'=>'kcommaaccent',
 310          'Lcedilla'=>'Lcommaaccent','lcedilla'=>'lcommaaccent','Ncedilla'=>'Ncommaaccent','ncedilla'=>'ncommaaccent',
 311          'Rcedilla'=>'Rcommaaccent','rcedilla'=>'rcommaaccent','Scedilla'=>'Scommaaccent','scedilla'=>'scommaaccent',
 312          'Tcedilla'=>'Tcommaaccent','tcedilla'=>'tcommaaccent','Dslash'=>'Dcroat','dslash'=>'dcroat','Dmacron'=>'Dcroat','dmacron'=>'dcroat',
 313          'combininggraveaccent'=>'gravecomb','combininghookabove'=>'hookabovecomb','combiningtildeaccent'=>'tildecomb',
 314          'combiningacuteaccent'=>'acutecomb','combiningdotbelow'=>'dotbelowcomb','dongsign'=>'dong');
 315      foreach($a as $l) {
 316          $e = explode(' ',rtrim($l));
 317          if (count($e) < 2) {
 318              continue;
 319          }
 320          $code = $e[0];
 321          $param = $e[1];
 322          if ($code == 'C') {
 323              //Character metrics
 324              $cc = (int)$e[1];
 325              $w = $e[4];
 326              $gn = $e[7];
 327              if(substr($gn,-4) == '20AC') {
 328                  $gn = 'Euro';
 329              }
 330              if (isset($fix[$gn])) {
 331                  //Fix incorrect glyph name
 332                  foreach ($map as $c => $n) {
 333                      if ($n == $fix[$gn]) {
 334                          $map[$c] = $gn;
 335                      }
 336                  }
 337              }
 338              if (empty($map)) {
 339                  //Symbolic font: use built-in encoding
 340                  $widths[$cc] = $w;
 341              } else {
 342                  $widths[$gn] = $w;
 343                  if($gn == 'X') {
 344                      $fm['CapXHeight'] = $e[13];
 345                  }
 346              }
 347              if($gn == '.notdef') {
 348                  $fm['MissingWidth'] = $w;
 349              }
 350          } elseif($code=='FontName') {
 351              $fm['FontName']=$param;
 352          } elseif($code=='Weight') {
 353              $fm['Weight']=$param;
 354          } elseif($code=='ItalicAngle') {
 355              $fm['ItalicAngle']=(double)$param;
 356          } elseif($code=='Ascender') {
 357              $fm['Ascender']=(int)$param;
 358          } elseif($code=='Descender') {
 359              $fm['Descender']=(int)$param;
 360          } elseif($code=='UnderlineThickness') {
 361              $fm['UnderlineThickness']=(int)$param;
 362          } elseif($code=='UnderlinePosition') {
 363              $fm['UnderlinePosition']=(int)$param;
 364          } elseif($code=='IsFixedPitch') {
 365              $fm['IsFixedPitch']=($param=='true');
 366          } elseif($code=='FontBBox') {
 367              $fm['FontBBox']=array($e[1],$e[2],$e[3],$e[4]);
 368          } elseif($code=='CapHeight') {
 369              $fm['CapHeight']=(int)$param;
 370          } elseif($code=='StdVW') {
 371              $fm['StdVW']=(int)$param;
 372          }
 373      }
 374      if (!isset($fm['FontName'])) {
 375          die('FontName not found');
 376      }
 377      if (!empty($map)) {
 378          if (!isset($widths['.notdef'])) {
 379              $widths['.notdef'] = 600;
 380          }
 381          if (!isset($widths['Delta']) AND isset($widths['increment'])) {
 382              $widths['Delta']=$widths['increment'];
 383          }
 384          //Order widths according to map
 385          for ($i=0; $i <= 255; $i++) {
 386              if (!isset($widths[$map[$i]])) {
 387                  print "Warning: character ".$map[$i]." is missing\n";
 388                  $widths[$i] = $widths['.notdef'];
 389              } else {
 390                  $widths[$i] = $widths[$map[$i]];
 391              }
 392          }
 393      }
 394      $fm['Widths'] = $widths;
 395      return $fm;
 396  }
 397  
 398  function MakeFontDescriptor($fm, $symbolic = false) {
 399      //Ascent
 400      $asc = (isset($fm['Ascender']) ? $fm['Ascender'] : 1000);
 401      $fd = "array('Ascent'=>".$asc;
 402      //Descent
 403      $desc = (isset($fm['Descender']) ? $fm['Descender'] : -200);
 404      $fd .= ",'Descent'=>".$desc;
 405      //CapHeight
 406      if (isset($fm['CapHeight'])) {
 407          $ch=$fm['CapHeight'];
 408      } elseif (isset($fm['CapXHeight'])) {
 409          $ch=$fm['CapXHeight'];
 410      } else {
 411          $ch = $asc;
 412      }
 413      $fd .= ",'CapHeight'=>".$ch;
 414      //Flags
 415      $flags = 0;
 416      if (isset($fm['IsFixedPitch']) AND $fm['IsFixedPitch']) {
 417          $flags += 1<<0;
 418      }
 419      if ($symbolic) {
 420          $flags += 1<<2;
 421      } else {
 422          $flags += 1<<5;
 423      }
 424      if (isset($fm['ItalicAngle']) AND ($fm['ItalicAngle'] != 0)) {
 425          $flags += 1<<6;
 426      }
 427      $fd .= ",'Flags'=>".$flags;
 428      //FontBBox
 429      if (isset($fm['FontBBox'])) {
 430          $fbb = $fm['FontBBox'];
 431      } else {
 432          $fbb = array(0, $desc-100, 1000, $asc+100);
 433      }
 434      $fd .= ",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'";
 435      //ItalicAngle
 436      $ia = (isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0);
 437      $fd .= ",'ItalicAngle'=>".$ia;
 438      //StemV
 439      if (isset($fm['StdVW'])) {
 440          $stemv = $fm['StdVW'];
 441      } elseif (isset($fm['Weight']) and eregi('(bold|black)',$fm['Weight'])) {
 442          $stemv=120;
 443      } else {
 444          $stemv = 70;
 445      }
 446      $fd .= ",'StemV'=>".$stemv;
 447      //MissingWidth
 448      if(isset($fm['MissingWidth'])) {
 449          $fd .= ",'MissingWidth'=>".$fm['MissingWidth'];
 450      }
 451      $fd .= ')';
 452      return $fd;
 453  }
 454  
 455  function MakeWidthArray($fm) {
 456      //Make character width array
 457      $s = "array(";
 458      $cw = $fm['Widths'];
 459      $els = array();
 460      $c = 0;
 461      foreach ($cw as $i => $w) {
 462          if (is_numeric($i)) {
 463              $els[] = $i.'=>'.$w;
 464          }
 465      }
 466      $s .= implode(',', $els);
 467      $s .= ')';
 468      return $s;
 469  }
 470  
 471  function MakeFontEncoding($map) {
 472      //Build differences from reference encoding
 473      $ref = ReadMap('cp1252');
 474      $s = '';
 475      $last = 0;
 476      for ($i=32; $i <= 255; $i++) {
 477          if ($map[$i] != $ref[$i]) {
 478              if ($i != $last+1) {
 479                  $s .= $i.' ';
 480              }
 481              $last = $i;
 482              $s .= '/'.$map[$i].' ';
 483          }
 484      }
 485      return rtrim($s);
 486  }
 487  
 488  function SaveToFile($file, $s, $mode='t') {
 489      $f = fopen($file, 'w'.$mode);
 490      if(!$f) {
 491          die('Can\'t write to file '.$file);
 492      }
 493      fwrite($f, $s, strlen($s));
 494      fclose($f);
 495  }
 496  
 497  function ReadShort($f) {
 498      $a = unpack('n1n',fread($f,2));
 499      return $a['n'];
 500  }
 501  
 502  function ReadLong($f) {
 503      $a = unpack('N1N',fread($f,4));
 504      return $a['N'];
 505  }
 506  
 507  function CheckTTF($file) {
 508      //Check if font license allows embedding
 509      $f = fopen($file,'rb');
 510      if(!$f) {
 511          die('Error: unable to open '.$file);
 512      }
 513      //Extract number of tables
 514      fseek($f, 4, SEEK_CUR);
 515      $nb = ReadShort($f);
 516      fseek($f, 6, SEEK_CUR);
 517      //Seek OS/2 table
 518      $found = false;
 519      for ($i=0; $i < $nb; $i++) {
 520          if (fread($f,4)=='OS/2') {
 521              $found = true;
 522              break;
 523          }
 524          fseek($f, 12, SEEK_CUR);
 525      }
 526      if(!$found) {
 527          fclose($f);
 528          return;
 529      }
 530      fseek($f, 4, SEEK_CUR);
 531      $offset = ReadLong($f);
 532      fseek($f, $offset, SEEK_SET);
 533      //Extract fsType flags
 534      fseek($f, 8, SEEK_CUR);
 535      $fsType = ReadShort($f);
 536      $rl = ($fsType & 0x02)!=0;
 537      $pp = ($fsType & 0x04)!=0;
 538      $e = ($fsType & 0x08)!=0;
 539      fclose($f);
 540      if($rl AND (!$pp) AND (!$e)) {
 541          print "Warning: font license does not allow embedding\n";
 542      }
 543  }
 544  
 545  $arg = $GLOBALS['argv'];
 546  if (count($arg) >= 3) {
 547      ob_start();
 548      array_shift($arg);
 549      if (!isset($arg[2])) {
 550          $arg[2] = true;
 551      }
 552      if (!isset($arg[3])) {
 553          $arg[3] = 'cp1252';
 554      }
 555      if (!isset($arg[4])) {
 556          $arg[4] = array();
 557      }
 558      MakeFont($arg[0], $arg[1], $arg[2], $arg[3], $arg[4]);
 559      $t = ob_get_clean();
 560      print preg_replace('!<BR( /)?>!i', "\n", $t);
 561  } else {
 562      print "Usage: makefont.php <ttf/otf/pfb file> <afm/ufm file> <encoding> <patch>\n";
 563  }
 564  ?>


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1