source: trunk/spip/esqueleto-redcta/plugins/article_pdf/pdf/font/makefont/makefont.php @ 30

Last change on this file since 30 was 30, checked in by sebas, 17 years ago

nueva importacion del codigo del esqueleto de redcta con los plugins

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