Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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