To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / .svn / pristine / 48 / 48150294b5e1667be0e02136382437b7ee17a5da.svn-base @ 1298:4f746d8966dd

History | View | Annotate | Download (8.36 KB)

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
?>