comparison vendor/plugins/rfpdf/lib/fonts/ttf2ufm/makefontuni_ruby.php @ 441:cbce1fd3b1b7 redmine-1.2

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