Annotation of /com_supacart/trunk/admin_files/classes/pdf/font/makefont/makefont.php
Parent Directory
|
Revision Log
Revision 4 - (view) (download)
| 1 : | andphe | 4 | <?php |
| 2 : | /** | ||
| 3 : | * @version $Id: makefont.php 617 2007-01-04 19:43:08Z soeren_nb $ | ||
| 4 : | * @package SupaCart | ||
| 5 : | * @subpackage HMTL2PDF | ||
| 6 : | * See COPYRIGHT.php for copyright notices and details. | ||
| 7 : | * @license GNU/GPL Version 2, see LICENSE.php | ||
| 8 : | * SupaCart is free software, originally derived from Virtuemart. This version may have been modified pursuant | ||
| 9 : | * to the GNU General Public License, and as distributed it includes or | ||
| 10 : | * is derivative of works licensed under the GNU General Public License or | ||
| 11 : | * other free or open source software licenses. | ||
| 12 : | * See /administrator/components/com_supacart/COPYRIGHT.php for copyright notices and details. | ||
| 13 : | * | ||
| 14 : | * http://www.supacart.com | ||
| 15 : | */ | ||
| 16 : | /******************************************************************************* | ||
| 17 : | * Utility to generate font definition files * | ||
| 18 : | * Version: 1.12 * | ||
| 19 : | * Date: 2003-12-30 * | ||
| 20 : | *******************************************************************************/ | ||
| 21 : | |||
| 22 : | function ReadMap($enc) | ||
| 23 : | { | ||
| 24 : | //Read a map file | ||
| 25 : | $file=dirname(__FILE__).'/'.strtolower($enc).'.map'; | ||
| 26 : | $a=file($file); | ||
| 27 : | if(empty($a)) | ||
| 28 : | die('<B>Error:</B> encoding not found: '.$enc); | ||
| 29 : | $cc2gn=array(); | ||
| 30 : | foreach($a as $l) | ||
| 31 : | { | ||
| 32 : | if($l{0}=='!') | ||
| 33 : | { | ||
| 34 : | $e=preg_split('/[ \\t]+/',chop($l)); | ||
| 35 : | $cc=hexdec(substr($e[0],1)); | ||
| 36 : | $gn=$e[2]; | ||
| 37 : | $cc2gn[$cc]=$gn; | ||
| 38 : | } | ||
| 39 : | } | ||
| 40 : | for($i=0;$i<=255;$i++) | ||
| 41 : | if(!isset($cc2gn[$i])) | ||
| 42 : | $cc2gn[$i]='.notdef'; | ||
| 43 : | return $cc2gn; | ||
| 44 : | } | ||
| 45 : | |||
| 46 : | function ReadAFM($file,&$map) | ||
| 47 : | { | ||
| 48 : | //Read a font metric file | ||
| 49 : | $a=file($file); | ||
| 50 : | if(empty($a)) | ||
| 51 : | die('File not found'); | ||
| 52 : | $widths=array(); | ||
| 53 : | $fm=array(); | ||
| 54 : | $fix=array('Edot'=>'Edotaccent','edot'=>'edotaccent','Idot'=>'Idotaccent','Zdot'=>'Zdotaccent','zdot'=>'zdotaccent', | ||
| 55 : | 'Odblacute'=>'Ohungarumlaut','odblacute'=>'ohungarumlaut','Udblacute'=>'Uhungarumlaut','udblacute'=>'uhungarumlaut', | ||
| 56 : | 'Gcedilla'=>'Gcommaaccent','gcedilla'=>'gcommaaccent','Kcedilla'=>'Kcommaaccent','kcedilla'=>'kcommaaccent', | ||
| 57 : | 'Lcedilla'=>'Lcommaaccent','lcedilla'=>'lcommaaccent','Ncedilla'=>'Ncommaaccent','ncedilla'=>'ncommaaccent', | ||
| 58 : | 'Rcedilla'=>'Rcommaaccent','rcedilla'=>'rcommaaccent','Scedilla'=>'Scommaaccent','scedilla'=>'scommaaccent', | ||
| 59 : | 'Tcedilla'=>'Tcommaaccent','tcedilla'=>'tcommaaccent','Dslash'=>'Dcroat','dslash'=>'dcroat','Dmacron'=>'Dcroat','dmacron'=>'dcroat', | ||
| 60 : | 'combininggraveaccent'=>'gravecomb','combininghookabove'=>'hookabovecomb','combiningtildeaccent'=>'tildecomb', | ||
| 61 : | 'combiningacuteaccent'=>'acutecomb','combiningdotbelow'=>'dotbelowcomb','dongsign'=>'dong'); | ||
| 62 : | foreach($a as $l) | ||
| 63 : | { | ||
| 64 : | $e=explode(' ',chop($l)); | ||
| 65 : | if(count($e)<2) | ||
| 66 : | continue; | ||
| 67 : | $code=$e[0]; | ||
| 68 : | $param=$e[1]; | ||
| 69 : | if($code=='C') | ||
| 70 : | { | ||
| 71 : | //Character metrics | ||
| 72 : | $cc=(int)$e[1]; | ||
| 73 : | $w=$e[4]; | ||
| 74 : | $gn=$e[7]; | ||
| 75 : | if(substr($gn,-4)=='20AC') | ||
| 76 : | $gn='Euro'; | ||
| 77 : | if(isset($fix[$gn])) | ||
| 78 : | { | ||
| 79 : | //Fix incorrect glyph name | ||
| 80 : | foreach($map as $c=>$n) | ||
| 81 : | if($n==$fix[$gn]) | ||
| 82 : | $map[$c]=$gn; | ||
| 83 : | } | ||
| 84 : | if(empty($map)) | ||
| 85 : | { | ||
| 86 : | //Symbolic font: use built-in encoding | ||
| 87 : | $widths[$cc]=$w; | ||
| 88 : | } | ||
| 89 : | else | ||
| 90 : | { | ||
| 91 : | $widths[$gn]=$w; | ||
| 92 : | if($gn=='X') | ||
| 93 : | $fm['CapXHeight']=$e[13]; | ||
| 94 : | } | ||
| 95 : | if($gn=='.notdef') | ||
| 96 : | $fm['MissingWidth']=$w; | ||
| 97 : | } | ||
| 98 : | elseif($code=='FontName') | ||
| 99 : | $fm['FontName']=$param; | ||
| 100 : | elseif($code=='Weight') | ||
| 101 : | $fm['Weight']=$param; | ||
| 102 : | elseif($code=='ItalicAngle') | ||
| 103 : | $fm['ItalicAngle']=(double)$param; | ||
| 104 : | elseif($code=='Ascender') | ||
| 105 : | $fm['Ascender']=(int)$param; | ||
| 106 : | elseif($code=='Descender') | ||
| 107 : | $fm['Descender']=(int)$param; | ||
| 108 : | elseif($code=='UnderlineThickness') | ||
| 109 : | $fm['UnderlineThickness']=(int)$param; | ||
| 110 : | elseif($code=='UnderlinePosition') | ||
| 111 : | $fm['UnderlinePosition']=(int)$param; | ||
| 112 : | elseif($code=='IsFixedPitch') | ||
| 113 : | $fm['IsFixedPitch']=($param=='true'); | ||
| 114 : | elseif($code=='FontBBox') | ||
| 115 : | $fm['FontBBox']=array($e[1],$e[2],$e[3],$e[4]); | ||
| 116 : | elseif($code=='CapHeight') | ||
| 117 : | $fm['CapHeight']=(int)$param; | ||
| 118 : | elseif($code=='StdVW') | ||
| 119 : | $fm['StdVW']=(int)$param; | ||
| 120 : | } | ||
| 121 : | if(!isset($fm['FontName'])) | ||
| 122 : | die('FontName not found'); | ||
| 123 : | if(!empty($map)) | ||
| 124 : | { | ||
| 125 : | if(!isset($widths['.notdef'])) | ||
| 126 : | $widths['.notdef']=600; | ||
| 127 : | if(!isset($widths['Delta']) and isset($widths['increment'])) | ||
| 128 : | $widths['Delta']=$widths['increment']; | ||
| 129 : | //Order widths according to map | ||
| 130 : | for($i=0;$i<=255;$i++) | ||
| 131 : | { | ||
| 132 : | if(!isset($widths[$map[$i]])) | ||
| 133 : | { | ||
| 134 : | echo '<B>Warning:</B> character '.$map[$i].' is missing<BR>'; | ||
| 135 : | $widths[$i]=$widths['.notdef']; | ||
| 136 : | } | ||
| 137 : | else | ||
| 138 : | $widths[$i]=$widths[$map[$i]]; | ||
| 139 : | } | ||
| 140 : | } | ||
| 141 : | $fm['Widths']=$widths; | ||
| 142 : | return $fm; | ||
| 143 : | } | ||
| 144 : | |||
| 145 : | function MakeFontDescriptor($fm,$symbolic) | ||
| 146 : | { | ||
| 147 : | //Ascent | ||
| 148 : | $asc=(isset($fm['Ascender']) ? $fm['Ascender'] : 1000); | ||
| 149 : | $fd="array('Ascent'=>".$asc; | ||
| 150 : | //Descent | ||
| 151 : | $desc=(isset($fm['Descender']) ? $fm['Descender'] : -200); | ||
| 152 : | $fd.=",'Descent'=>".$desc; | ||
| 153 : | //CapHeight | ||
| 154 : | if(isset($fm['CapHeight'])) | ||
| 155 : | $ch=$fm['CapHeight']; | ||
| 156 : | elseif(isset($fm['CapXHeight'])) | ||
| 157 : | $ch=$fm['CapXHeight']; | ||
| 158 : | else | ||
| 159 : | $ch=$asc; | ||
| 160 : | $fd.=",'CapHeight'=>".$ch; | ||
| 161 : | //Flags | ||
| 162 : | $flags=0; | ||
| 163 : | if(isset($fm['IsFixedPitch']) and $fm['IsFixedPitch']) | ||
| 164 : | $flags+=1<<0; | ||
| 165 : | if($symbolic) | ||
| 166 : | $flags+=1<<2; | ||
| 167 : | if(!$symbolic) | ||
| 168 : | $flags+=1<<5; | ||
| 169 : | if(isset($fm['ItalicAngle']) and $fm['ItalicAngle']!=0) | ||
| 170 : | $flags+=1<<6; | ||
| 171 : | $fd.=",'Flags'=>".$flags; | ||
| 172 : | //FontBBox | ||
| 173 : | if(isset($fm['FontBBox'])) | ||
| 174 : | $fbb=$fm['FontBBox']; | ||
| 175 : | else | ||
| 176 : | $fbb=array(0,$des-100,1000,$asc+100); | ||
| 177 : | $fd.=",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'"; | ||
| 178 : | //ItalicAngle | ||
| 179 : | $ia=(isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0); | ||
| 180 : | $fd.=",'ItalicAngle'=>".$ia; | ||
| 181 : | //StemV | ||
| 182 : | if(isset($fm['StdVW'])) | ||
| 183 : | $stemv=$fm['StdVW']; | ||
| 184 : | elseif(isset($fm['Weight']) and eregi('(bold|black)',$fm['Weight'])) | ||
| 185 : | $stemv=120; | ||
| 186 : | else | ||
| 187 : | $stemv=70; | ||
| 188 : | $fd.=",'StemV'=>".$stemv; | ||
| 189 : | //MissingWidth | ||
| 190 : | if(isset($fm['MissingWidth'])) | ||
| 191 : | $fd.=",'MissingWidth'=>".$fm['MissingWidth']; | ||
| 192 : | $fd.=')'; | ||
| 193 : | return $fd; | ||
| 194 : | } | ||
| 195 : | |||
| 196 : | function MakeWidthArray($fm) | ||
| 197 : | { | ||
| 198 : | //Make character width array | ||
| 199 : | $s="array(\n\t"; | ||
| 200 : | $cw=$fm['Widths']; | ||
| 201 : | for($i=0;$i<=255;$i++) | ||
| 202 : | { | ||
| 203 : | if(chr($i)=="'") | ||
| 204 : | $s.="'\\''"; | ||
| 205 : | elseif(chr($i)=="\\") | ||
| 206 : | $s.="'\\\\'"; | ||
| 207 : | elseif($i>=32 and $i<=126) | ||
| 208 : | $s.="'".chr($i)."'"; | ||
| 209 : | else | ||
| 210 : | $s.="chr($i)"; | ||
| 211 : | $s.='=>'.$fm['Widths'][$i]; | ||
| 212 : | if($i<255) | ||
| 213 : | $s.=','; | ||
| 214 : | if(($i+1)%22==0) | ||
| 215 : | $s.="\n\t"; | ||
| 216 : | } | ||
| 217 : | $s.=')'; | ||
| 218 : | return $s; | ||
| 219 : | } | ||
| 220 : | |||
| 221 : | function MakeFontEncoding($map) | ||
| 222 : | { | ||
| 223 : | //Build differences from reference encoding | ||
| 224 : | $ref=ReadMap('cp1252'); | ||
| 225 : | $s=''; | ||
| 226 : | $last=0; | ||
| 227 : | for($i=32;$i<=255;$i++) | ||
| 228 : | { | ||
| 229 : | if($map[$i]!=$ref[$i]) | ||
| 230 : | { | ||
| 231 : | if($i!=$last+1) | ||
| 232 : | $s.=$i.' '; | ||
| 233 : | $last=$i; | ||
| 234 : | $s.='/'.$map[$i].' '; | ||
| 235 : | } | ||
| 236 : | } | ||
| 237 : | return chop($s); | ||
| 238 : | } | ||
| 239 : | |||
| 240 : | function SaveToFile($file,$s,$mode='t') | ||
| 241 : | { | ||
| 242 : | $f=fopen($file,'w'.$mode); | ||
| 243 : | if(!$f) | ||
| 244 : | die('Can\'t write to file '.$file); | ||
| 245 : | fwrite($f,$s,strlen($s)); | ||
| 246 : | fclose($f); | ||
| 247 : | } | ||
| 248 : | |||
| 249 : | function ReadShort($f) | ||
| 250 : | { | ||
| 251 : | $a=unpack('n1n',fread($f,2)); | ||
| 252 : | return $a['n']; | ||
| 253 : | } | ||
| 254 : | |||
| 255 : | function ReadLong($f) | ||
| 256 : | { | ||
| 257 : | $a=unpack('N1N',fread($f,4)); | ||
| 258 : | return $a['N']; | ||
| 259 : | } | ||
| 260 : | |||
| 261 : | function CheckTTF($file) | ||
| 262 : | { | ||
| 263 : | //Check if font license allows embedding | ||
| 264 : | $f=fopen($file,'rb'); | ||
| 265 : | if(!$f) | ||
| 266 : | die('<B>Error:</B> Can\'t open '.$file); | ||
| 267 : | //Extract number of tables | ||
| 268 : | fseek($f,4,SEEK_CUR); | ||
| 269 : | $nb=ReadShort($f); | ||
| 270 : | fseek($f,6,SEEK_CUR); | ||
| 271 : | //Seek OS/2 table | ||
| 272 : | $found=false; | ||
| 273 : | for($i=0;$i<$nb;$i++) | ||
| 274 : | { | ||
| 275 : | if(fread($f,4)=='OS/2') | ||
| 276 : | { | ||
| 277 : | $found=true; | ||
| 278 : | break; | ||
| 279 : | } | ||
| 280 : | fseek($f,12,SEEK_CUR); | ||
| 281 : | } | ||
| 282 : | if(!$found) | ||
| 283 : | { | ||
| 284 : | fclose($f); | ||
| 285 : | return; | ||
| 286 : | } | ||
| 287 : | fseek($f,4,SEEK_CUR); | ||
| 288 : | $offset=ReadLong($f); | ||
| 289 : | fseek($f,$offset,SEEK_SET); | ||
| 290 : | //Extract fsType flags | ||
| 291 : | fseek($f,8,SEEK_CUR); | ||
| 292 : | $fsType=ReadShort($f); | ||
| 293 : | $rl=($fsType & 0x02)!=0; | ||
| 294 : | $pp=($fsType & 0x04)!=0; | ||
| 295 : | $e=($fsType & 0x08)!=0; | ||
| 296 : | fclose($f); | ||
| 297 : | if($rl and !$pp and !$e) | ||
| 298 : | echo '<B>Warning:</B> font license does not allow embedding'; | ||
| 299 : | } | ||
| 300 : | |||
| 301 : | /******************************************************************************* | ||
| 302 : | * $fontfile: path to TTF file (or empty string if not to be embedded) * | ||
| 303 : | * $afmfile: path to AFM file * | ||
| 304 : | * $enc: font encoding (or empty string for symbolic fonts) * | ||
| 305 : | * $patch: optional patch for encoding * | ||
| 306 : | * $type : font type if $fontfile is empty * | ||
| 307 : | *******************************************************************************/ | ||
| 308 : | function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=array(),$type='TrueType') | ||
| 309 : | { | ||
| 310 : | //Generate a font definition file | ||
| 311 : | set_magic_quotes_runtime(0); | ||
| 312 : | if($enc) | ||
| 313 : | { | ||
| 314 : | $map=ReadMap($enc); | ||
| 315 : | foreach($patch as $cc=>$gn) | ||
| 316 : | $map[$cc]=$gn; | ||
| 317 : | } | ||
| 318 : | else | ||
| 319 : | $map=array(); | ||
| 320 : | if(!file_exists($afmfile)) | ||
| 321 : | die('<B>Error:</B> AFM file not found: '.$afmfile); | ||
| 322 : | $fm=ReadAFM($afmfile,$map); | ||
| 323 : | if($enc) | ||
| 324 : | $diff=MakeFontEncoding($map); | ||
| 325 : | else | ||
| 326 : | $diff=''; | ||
| 327 : | $fd=MakeFontDescriptor($fm,empty($map)); | ||
| 328 : | //Find font type | ||
| 329 : | if($fontfile) | ||
| 330 : | { | ||
| 331 : | $ext=strtolower(substr($fontfile,-3)); | ||
| 332 : | if($ext=='ttf') | ||
| 333 : | $type='TrueType'; | ||
| 334 : | elseif($ext=='pfb') | ||
| 335 : | $type='Type1'; | ||
| 336 : | else | ||
| 337 : | die('<B>Error:</B> unrecognized font file extension: '.$ext); | ||
| 338 : | } | ||
| 339 : | else | ||
| 340 : | { | ||
| 341 : | if($type!='TrueType' and $type!='Type1') | ||
| 342 : | die('<B>Error:</B> incorrect font type: '.$type); | ||
| 343 : | } | ||
| 344 : | //Start generation | ||
| 345 : | $s='<?php'."\n"; | ||
| 346 : | $s.='$type=\''.$type."';\n"; | ||
| 347 : | $s.='$name=\''.$fm['FontName']."';\n"; | ||
| 348 : | $s.='$desc='.$fd.";\n"; | ||
| 349 : | if(!isset($fm['UnderlinePosition'])) | ||
| 350 : | $fm['UnderlinePosition']=-100; | ||
| 351 : | if(!isset($fm['UnderlineThickness'])) | ||
| 352 : | $fm['UnderlineThickness']=50; | ||
| 353 : | $s.='$up='.$fm['UnderlinePosition'].";\n"; | ||
| 354 : | $s.='$ut='.$fm['UnderlineThickness'].";\n"; | ||
| 355 : | $w=MakeWidthArray($fm); | ||
| 356 : | $s.='$cw='.$w.";\n"; | ||
| 357 : | $s.='$enc=\''.$enc."';\n"; | ||
| 358 : | $s.='$diff=\''.$diff."';\n"; | ||
| 359 : | $basename=substr(basename($afmfile),0,-4); | ||
| 360 : | if($fontfile) | ||
| 361 : | { | ||
| 362 : | //Embedded font | ||
| 363 : | if(!file_exists($fontfile)) | ||
| 364 : | die('<B>Error:</B> font file not found: '.$fontfile); | ||
| 365 : | if($type=='TrueType') | ||
| 366 : | CheckTTF($fontfile); | ||
| 367 : | $f=fopen($fontfile,'rb'); | ||
| 368 : | if(!$f) | ||
| 369 : | die('<B>Error:</B> Can\'t open '.$fontfile); | ||
| 370 : | $file=fread($f,filesize($fontfile)); | ||
| 371 : | fclose($f); | ||
| 372 : | if($type=='Type1') | ||
| 373 : | { | ||
| 374 : | //Find first two sections and discard third one | ||
| 375 : | $pos=strpos($file,'eexec'); | ||
| 376 : | if(!$pos) | ||
| 377 : | die('<B>Error:</B> font file does not seem to be valid Type1'); | ||
| 378 : | $size1=$pos+6; | ||
| 379 : | $pos=strpos($file,'00000000'); | ||
| 380 : | if(!$pos) | ||
| 381 : | die('<B>Error:</B> font file does not seem to be valid Type1'); | ||
| 382 : | $size2=$pos-$size1; | ||
| 383 : | $file=substr($file,0,$size1+$size2); | ||
| 384 : | } | ||
| 385 : | if(function_exists('gzcompress')) | ||
| 386 : | { | ||
| 387 : | $cmp=$basename.'.z'; | ||
| 388 : | SaveToFile($cmp,gzcompress($file),'b'); | ||
| 389 : | $s.='$file=\''.$cmp."';\n"; | ||
| 390 : | echo 'Font file compressed ('.$cmp.')<BR>'; | ||
| 391 : | } | ||
| 392 : | else | ||
| 393 : | { | ||
| 394 : | $s.='$file=\''.basename($fontfile)."';\n"; | ||
| 395 : | echo '<B>Notice:</B> font file could not be compressed (gzcompress not available)<BR>'; | ||
| 396 : | } | ||
| 397 : | if($type=='Type1') | ||
| 398 : | { | ||
| 399 : | $s.='$size1='.$size1.";\n"; | ||
| 400 : | $s.='$size2='.$size2.";\n"; | ||
| 401 : | } | ||
| 402 : | else | ||
| 403 : | $s.='$originalsize='.filesize($fontfile).";\n"; | ||
| 404 : | } | ||
| 405 : | else | ||
| 406 : | { | ||
| 407 : | //Not embedded font | ||
| 408 : | $s.='$file='."'';\n"; | ||
| 409 : | } | ||
| 410 : | $s.="?>\n"; | ||
| 411 : | SaveToFile($basename.'.php',$s); | ||
| 412 : | echo 'Font definition file generated ('.$basename.'.php'.')<BR>'; | ||
| 413 : | } | ||
| 414 : | ?> |
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |
Web Hosting provided by Network Redux.

