annotate vendor/plugins/rfpdf/lib/fonts/ttf2ufm/makefontuni_ruby.php @ 1477:f2ad2199b49a bibplugin_integration

Close obsolete branch bibplugin_integration
author Chris Cannam
date Fri, 30 Nov 2012 14:41:31 +0000
parents cbce1fd3b1b7
children
rev   line source
Chris@441 1 <?php
Chris@441 2 /*******************************************************************************
Chris@441 3 * Utility to generate font definition files for Unicode Truetype fonts *
Chris@441 4 * Version: 1.12 *
Chris@441 5 * Date: 2003-12-30 *
Chris@441 6 *******************************************************************************/
Chris@441 7
Chris@441 8 function ReadUFM($file, &$cidtogidmap)
Chris@441 9 {
Chris@441 10 //Prepare empty CIDToGIDMap
Chris@441 11 $cidtogidmap = str_pad('', 256*256*2, "\x00");
Chris@441 12
Chris@441 13 //Read a font metric file
Chris@441 14 $a=file($file);
Chris@441 15 if(empty($a))
Chris@441 16 die('File not found');
Chris@441 17 $widths=array();
Chris@441 18 $fm=array();
Chris@441 19 foreach($a as $l)
Chris@441 20 {
Chris@441 21 $e=explode(' ',chop($l));
Chris@441 22 if(count($e)<2)
Chris@441 23 continue;
Chris@441 24 $code=$e[0];
Chris@441 25 $param=$e[1];
Chris@441 26 if($code=='U')
Chris@441 27 {
Chris@441 28 // U 827 ; WX 0 ; N squaresubnosp ; G 675 ;
Chris@441 29 //Character metrics
Chris@441 30 $cc=(int)$e[1];
Chris@441 31 if ($cc != -1) {
Chris@441 32 $gn = $e[7];
Chris@441 33 $w = $e[4];
Chris@441 34 $glyph = $e[10];
Chris@441 35 $widths[$cc] = $w;
Chris@441 36 if($cc == ord('X'))
Chris@441 37 $fm['CapXHeight'] = $e[13];
Chris@441 38
Chris@441 39 // Set GID
Chris@441 40 if ($cc >= 0 && $cc < 0xFFFF && $glyph) {
Chris@441 41 $cidtogidmap{$cc*2} = chr($glyph >> 8);
Chris@441 42 $cidtogidmap{$cc*2 + 1} = chr($glyph & 0xFF);
Chris@441 43 }
Chris@441 44 }
Chris@441 45 if($gn=='.notdef' && !isset($fm['MissingWidth']))
Chris@441 46 $fm['MissingWidth']=$w;
Chris@441 47 }
Chris@441 48 elseif($code=='FontName')
Chris@441 49 $fm['FontName']=$param;
Chris@441 50 elseif($code=='Weight')
Chris@441 51 $fm['Weight']=$param;
Chris@441 52 elseif($code=='ItalicAngle')
Chris@441 53 $fm['ItalicAngle']=(double)$param;
Chris@441 54 elseif($code=='Ascender')
Chris@441 55 $fm['Ascender']=(int)$param;
Chris@441 56 elseif($code=='Descender')
Chris@441 57 $fm['Descender']=(int)$param;
Chris@441 58 elseif($code=='UnderlineThickness')
Chris@441 59 $fm['UnderlineThickness']=(int)$param;
Chris@441 60 elseif($code=='UnderlinePosition')
Chris@441 61 $fm['UnderlinePosition']=(int)$param;
Chris@441 62 elseif($code=='IsFixedPitch')
Chris@441 63 $fm['IsFixedPitch']=($param=='true');
Chris@441 64 elseif($code=='FontBBox')
Chris@441 65 $fm['FontBBox']=array($e[1],$e[2],$e[3],$e[4]);
Chris@441 66 elseif($code=='CapHeight')
Chris@441 67 $fm['CapHeight']=(int)$param;
Chris@441 68 elseif($code=='StdVW')
Chris@441 69 $fm['StdVW']=(int)$param;
Chris@441 70 }
Chris@441 71 if(!isset($fm['MissingWidth']))
Chris@441 72 $fm['MissingWidth']=600;
Chris@441 73
Chris@441 74 if(!isset($fm['FontName']))
Chris@441 75 die('FontName not found');
Chris@441 76
Chris@441 77 $fm['Widths']=$widths;
Chris@441 78
Chris@441 79 return $fm;
Chris@441 80 }
Chris@441 81
Chris@441 82 function MakeFontDescriptor($fm)
Chris@441 83 {
Chris@441 84 //Ascent
Chris@441 85 $asc=(isset($fm['Ascender']) ? $fm['Ascender'] : 1000);
Chris@441 86 $fd="{'Ascent'=>".$asc;
Chris@441 87 //Descent
Chris@441 88 $desc=(isset($fm['Descender']) ? $fm['Descender'] : -200);
Chris@441 89 $fd.=",'Descent'=>".$desc;
Chris@441 90 //CapHeight
Chris@441 91 if(isset($fm['CapHeight']))
Chris@441 92 $ch=$fm['CapHeight'];
Chris@441 93 elseif(isset($fm['CapXHeight']))
Chris@441 94 $ch=$fm['CapXHeight'];
Chris@441 95 else
Chris@441 96 $ch=$asc;
Chris@441 97 $fd.=",'CapHeight'=>".$ch;
Chris@441 98 //Flags
Chris@441 99 $flags=0;
Chris@441 100 if(isset($fm['IsFixedPitch']) and $fm['IsFixedPitch'])
Chris@441 101 $flags+=1<<0;
Chris@441 102 $flags+=1<<5;
Chris@441 103 if(isset($fm['ItalicAngle']) and $fm['ItalicAngle']!=0)
Chris@441 104 $flags+=1<<6;
Chris@441 105 $fd.=",'Flags'=>".$flags;
Chris@441 106 //FontBBox
Chris@441 107 if(isset($fm['FontBBox']))
Chris@441 108 $fbb=$fm['FontBBox'];
Chris@441 109 else
Chris@441 110 $fbb=array(0,$des-100,1000,$asc+100);
Chris@441 111 $fd.=",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'";
Chris@441 112 //ItalicAngle
Chris@441 113 $ia=(isset($fm['ItalicAngle']) ? $fm['ItalicAngle'] : 0);
Chris@441 114 $fd.=",'ItalicAngle'=>".$ia;
Chris@441 115 //StemV
Chris@441 116 if(isset($fm['StdVW']))
Chris@441 117 $stemv=$fm['StdVW'];
Chris@441 118 elseif(isset($fm['Weight']) and eregi('(bold|black)',$fm['Weight']))
Chris@441 119 $stemv=120;
Chris@441 120 else
Chris@441 121 $stemv=70;
Chris@441 122 $fd.=",'StemV'=>".$stemv;
Chris@441 123 //MissingWidth
Chris@441 124 if(isset($fm['MissingWidth']))
Chris@441 125 $fd.=",'MissingWidth'=>".$fm['MissingWidth'];
Chris@441 126 $fd.='}';
Chris@441 127 return $fd;
Chris@441 128 }
Chris@441 129
Chris@441 130 function MakeWidthArray($fm)
Chris@441 131 {
Chris@441 132 //Make character width array
Chris@441 133 $s="{";
Chris@441 134 $cw=$fm['Widths'];
Chris@441 135 $els=array();
Chris@441 136 $c=0;
Chris@441 137 foreach ($cw as $i => $w)
Chris@441 138 {
Chris@441 139 $els[] = ((($c++)%16==0)?"\n\t":'').$i.'=>'.$w;
Chris@441 140 }
Chris@441 141 $s .= implode(', ', $els);
Chris@441 142 $s.='}';
Chris@441 143 return $s;
Chris@441 144 }
Chris@441 145
Chris@441 146 function SaveToFile($file,$s,$mode='t')
Chris@441 147 {
Chris@441 148 $f=fopen($file,'w'.$mode);
Chris@441 149 if(!$f)
Chris@441 150 die('Can\'t write to file '.$file);
Chris@441 151 fwrite($f,$s,strlen($s));
Chris@441 152 fclose($f);
Chris@441 153 }
Chris@441 154
Chris@441 155 function ReadShort($f)
Chris@441 156 {
Chris@441 157 $a=unpack('n1n',fread($f,2));
Chris@441 158 return $a['n'];
Chris@441 159 }
Chris@441 160
Chris@441 161 function ReadLong($f)
Chris@441 162 {
Chris@441 163 $a=unpack('N1N',fread($f,4));
Chris@441 164 return $a['N'];
Chris@441 165 }
Chris@441 166
Chris@441 167 function CheckTTF($file)
Chris@441 168 {
Chris@441 169 //Check if font license allows embedding
Chris@441 170 $f=fopen($file,'rb');
Chris@441 171 if(!$f)
Chris@441 172 die('<B>Error:</B> Can\'t open '.$file);
Chris@441 173 //Extract number of tables
Chris@441 174 fseek($f,4,SEEK_CUR);
Chris@441 175 $nb=ReadShort($f);
Chris@441 176 fseek($f,6,SEEK_CUR);
Chris@441 177 //Seek OS/2 table
Chris@441 178 $found=false;
Chris@441 179 for($i=0;$i<$nb;$i++)
Chris@441 180 {
Chris@441 181 if(fread($f,4)=='OS/2')
Chris@441 182 {
Chris@441 183 $found=true;
Chris@441 184 break;
Chris@441 185 }
Chris@441 186 fseek($f,12,SEEK_CUR);
Chris@441 187 }
Chris@441 188 if(!$found)
Chris@441 189 {
Chris@441 190 fclose($f);
Chris@441 191 return;
Chris@441 192 }
Chris@441 193 fseek($f,4,SEEK_CUR);
Chris@441 194 $offset=ReadLong($f);
Chris@441 195 fseek($f,$offset,SEEK_SET);
Chris@441 196 //Extract fsType flags
Chris@441 197 fseek($f,8,SEEK_CUR);
Chris@441 198 $fsType=ReadShort($f);
Chris@441 199 $rl=($fsType & 0x02)!=0;
Chris@441 200 $pp=($fsType & 0x04)!=0;
Chris@441 201 $e=($fsType & 0x08)!=0;
Chris@441 202 fclose($f);
Chris@441 203 if($rl and !$pp and !$e)
Chris@441 204 echo '<B>Warning:</B> font license does not allow embedding';
Chris@441 205 }
Chris@441 206
Chris@441 207 /*******************************************************************************
Chris@441 208 * $fontfile: path to TTF file (or empty string if not to be embedded) *
Chris@441 209 * $ufmfile: path to UFM file *
Chris@441 210 *******************************************************************************/
Chris@441 211 function MakeFont($fontfile,$ufmfile)
Chris@441 212 {
Chris@441 213 //Generate a font definition file
Chris@441 214 set_magic_quotes_runtime(0);
Chris@441 215 if(!file_exists($ufmfile))
Chris@441 216 die('<B>Error:</B> UFM file not found: '.$ufmfile);
Chris@441 217 $cidtogidmap = '';
Chris@441 218 $fm=ReadUFM($ufmfile, $cidtogidmap);
Chris@441 219 $fd=MakeFontDescriptor($fm);
Chris@441 220 //Find font type
Chris@441 221 if($fontfile)
Chris@441 222 {
Chris@441 223 $ext=strtolower(substr($fontfile,-3));
Chris@441 224 if($ext=='ttf')
Chris@441 225 $type='TrueTypeUnicode';
Chris@441 226 else
Chris@441 227 die('<B>Error:</B> not a truetype font: '.$ext);
Chris@441 228 }
Chris@441 229 else
Chris@441 230 {
Chris@441 231 if($type!='TrueTypeUnicode')
Chris@441 232 die('<B>Error:</B> incorrect font type: '.$type);
Chris@441 233 }
Chris@441 234 //Start generation
Chris@441 235 $basename=strtolower(substr(basename($ufmfile),0,-4));
Chris@441 236 $s='TCPDFFontDescriptor.define(\''.$basename."') do |font|\n";
Chris@441 237 $s.=" font[:type]='".$type."'\n";
Chris@441 238 $s.=" font[:name]='".$fm['FontName']."'\n";
Chris@441 239 $s.=" font[:desc]=".$fd."\n";
Chris@441 240 if(!isset($fm['UnderlinePosition']))
Chris@441 241 $fm['UnderlinePosition']=-100;
Chris@441 242 if(!isset($fm['UnderlineThickness']))
Chris@441 243 $fm['UnderlineThickness']=50;
Chris@441 244 $s.=" font[:up]=".$fm['UnderlinePosition']."\n";
Chris@441 245 $s.=" font[:ut]=".$fm['UnderlineThickness']."\n";
Chris@441 246 $s.=" font[:cw]=".MakeWidthArray($fm)."\n";
Chris@441 247 $s.=" font[:enc]=''\n";
Chris@441 248 $s.=" font[:diff]=''\n";
Chris@441 249 if($fontfile)
Chris@441 250 {
Chris@441 251 //Embedded font
Chris@441 252 if(!file_exists($fontfile))
Chris@441 253 die('<B>Error:</B> font file not found: '.$fontfile);
Chris@441 254 CheckTTF($fontfile);
Chris@441 255 $f=fopen($fontfile,'rb');
Chris@441 256 if(!$f)
Chris@441 257 die('<B>Error:</B> Can\'t open '.$fontfile);
Chris@441 258 $file=fread($f,filesize($fontfile));
Chris@441 259 fclose($f);
Chris@441 260 if(function_exists('gzcompress'))
Chris@441 261 {
Chris@441 262 $cmp=$basename.'.z';
Chris@441 263 SaveToFile($cmp,gzcompress($file),'b');
Chris@441 264 $s.=' font[:file]=\''.$cmp."'\n";
Chris@441 265 echo 'Font file compressed ('.$cmp.')<BR>';
Chris@441 266
Chris@441 267 $cmp=$basename.'.ctg.z';
Chris@441 268 SaveToFile($cmp,gzcompress($cidtogidmap),'b');
Chris@441 269 echo 'CIDToGIDMap created and compressed ('.$cmp.')<BR>';
Chris@441 270 $s.=' font[:ctg]=\''.$cmp."'\n";
Chris@441 271 }
Chris@441 272 else
Chris@441 273 {
Chris@441 274 $s.='$file=\''.basename($fontfile)."'\n";
Chris@441 275 echo '<B>Notice:</B> font file could not be compressed (gzcompress not available)<BR>';
Chris@441 276
Chris@441 277 $cmp=$basename.'.ctg';
Chris@441 278 $f = fopen($cmp, 'wb');
Chris@441 279 fwrite($f, $cidtogidmap);
Chris@441 280 fclose($f);
Chris@441 281 echo 'CIDToGIDMap created ('.$cmp.')<BR>';
Chris@441 282 $s.=' font[:ctg]=\''.$cmp."'\n";
Chris@441 283 }
Chris@441 284 if($type=='Type1')
Chris@441 285 {
Chris@441 286 $s.=' font[:size1]='.$size1."\n";
Chris@441 287 $s.=' font[:size2]='.$size2."\n";
Chris@441 288 }
Chris@441 289 else
Chris@441 290 $s.=' font[:originalsize]='.filesize($fontfile)."\n";
Chris@441 291 }
Chris@441 292 else
Chris@441 293 {
Chris@441 294 //Not embedded font
Chris@441 295 $s.=' font[:file]='."''\n";
Chris@441 296 }
Chris@441 297 $s.="end\n";
Chris@441 298 SaveToFile($basename.'.rb',$s);
Chris@441 299 echo 'Font definition file generated ('.$basename.'.rb'.')<BR>';
Chris@441 300 }
Chris@441 301
Chris@441 302 $arg = $GLOBALS['argv'];
Chris@441 303 if (count($arg) >= 3) {
Chris@441 304 ob_start();
Chris@441 305 array_shift($arg);
Chris@441 306 MakeFont($arg[0], $arg[1]);
Chris@441 307 $t = ob_get_clean();
Chris@441 308 print preg_replace('!<BR( /)?>!i', "\n", $t);
Chris@441 309 }
Chris@441 310 else {
Chris@441 311 print "Usage: makefontuni_ruby.php <ttf-file> <ufm-file>\n";
Chris@441 312 }
Chris@441 313 ?>