diff .svn/pristine/b0/b00b19ae72ee99ad4406b689ee8ffd14f04ede96.svn-base @ 909:cbb26bc654de redmine-1.3

Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author Chris Cannam
date Fri, 24 Feb 2012 19:09:32 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.svn/pristine/b0/b00b19ae72ee99ad4406b689ee8ffd14f04ede96.svn-base	Fri Feb 24 19:09:32 2012 +0000
@@ -0,0 +1,411 @@
+
+#*****************************************************************************
+# Utility to generate font definition files                                   #
+# Version: 1.13                                                               #
+# Date:    2004-12-31                                                         #
+******************************************************************************#
+
+function ReadMap($enc)
+{
+	#Read a map file
+	$file=dirname(__FILE__) + '/' + $enc.downcase + '.map';
+	$a=file($file);
+	if ($a))
+		die('<B>Error:</B> encoding not found: '.$enc);
+	$cc2gn = []
+	foreach($a as $l)
+	{
+		if ($l{0}=='!')
+		{
+			$e=rtrim($l).scan('/[ \\t]+/');
+			$cc=hexdec(substr($e[0],1));
+			$gn=$e[2];
+			$cc2gn[$cc]=$gn;
+		end
+	end
+	for($i=0;$i<=255;$i++)
+	{
+		if (!$cc2gn[$i].nil?)
+			$cc2gn[$i]='.notdef';
+	end
+	return $cc2gn;
+}
+
+function ReadAFM($file,&$map)
+{
+	#Read a font metric file
+	$a=file($file);
+	if ($a.empty?)
+		die('File not found');
+	$widths = []
+	$fm = []
+	$fix=Hash.new('Edot'=>'Edotaccent','edot'=>'edotaccent','Idot'=>'Idotaccent','Zdot'=>'Zdotaccent','zdot'=>'zdotaccent',
+		'Odblacute'=>'Ohungarumlaut','odblacute'=>'ohungarumlaut','Udblacute'=>'Uhungarumlaut','udblacute'=>'uhungarumlaut',
+		'Gcedilla'=>'Gcommaaccent','gcedilla'=>'gcommaaccent','Kcedilla'=>'Kcommaaccent','kcedilla'=>'kcommaaccent',
+		'Lcedilla'=>'Lcommaaccent','lcedilla'=>'lcommaaccent','Ncedilla'=>'Ncommaaccent','ncedilla'=>'ncommaaccent',
+		'Rcedilla'=>'Rcommaaccent','rcedilla'=>'rcommaaccent','Scedilla'=>'Scommaaccent','scedilla'=>'scommaaccent',
+		'Tcedilla'=>'Tcommaaccent','tcedilla'=>'tcommaaccent','Dslash'=>'Dcroat','dslash'=>'dcroat','Dmacron'=>'Dcroat','dmacron'=>'dcroat',
+		'combininggraveaccent'=>'gravecomb','combininghookabove'=>'hookabovecomb','combiningtildeaccent'=>'tildecomb',
+		'combiningacuteaccent'=>'acutecomb','combiningdotbelow'=>'dotbelowcomb','dongsign'=>'dong');
+	foreach($a as $l)
+	{
+		$e=explode(' ',rtrim($l));
+		if ($e.length<2)
+			continue;
+		$code=$e[0];
+		$param=$e[1];
+		if ($code=='C')
+		{
+			#Character metrics
+			$cc=(int)$e[1];
+			$w=$e[4];
+			$gn=$e[7];
+			if (substr($gn,-4)=='20AC')
+				$gn='Euro';
+			if ($fix[$gn].nil?)
+			{
+				#Fix incorrect glyph name
+				foreach($map as $c=>$n)
+				{
+					if ($n==$fix[$gn])
+						$map[$c]=$gn;
+				end
+			end
+			if ($map.empty?)
+			{
+				#Symbolic font: use built-in encoding
+				$widths[$cc]=$w;
+			else
+			{
+				$widths[$gn]=$w;
+				if ($gn=='X')
+					$fm['CapXHeight']=$e[13];
+			end
+			if ($gn=='.notdef')
+				$fm['MissingWidth']=$w;
+		elsif ($code=='FontName')
+			$fm['FontName']=$param;
+		elsif ($code=='Weight')
+			$fm['Weight']=$param;
+		elsif ($code=='ItalicAngle')
+			$fm['ItalicAngle']=(double)$param;
+		elsif ($code=='Ascender')
+			$fm['Ascender']=(int)$param;
+		elsif ($code=='Descender')
+			$fm['Descender']=(int)$param;
+		elsif ($code=='UnderlineThickness')
+			$fm['UnderlineThickness']=(int)$param;
+		elsif ($code=='UnderlinePosition')
+			$fm['UnderlinePosition']=(int)$param;
+		elsif ($code=='IsFixedPitch')
+			$fm['IsFixedPitch']=($param=='true');
+		elsif ($code=='FontBBox')
+			$fm['FontBBox']=Hash.new($e[1],$e[2],$e[3],$e[4]);
+		elsif ($code=='CapHeight')
+			$fm['CapHeight']=(int)$param;
+		elsif ($code=='StdVW')
+			$fm['StdVW']=(int)$param;
+	end
+	if (!$fm['FontName'].nil?)
+		die('FontName not found');
+	if (!$map.empty?)
+	{
+		if (!$widths['.notdef'].nil?)
+			$widths['.notdef']=600;
+		if (!$widths['Delta'].nil? and $widths['increment'].nil?)
+			$widths['Delta']=$widths['increment'];
+		#Order widths according to map
+		for($i=0;$i<=255;$i++)
+		{
+			if (!$widths[$map[$i]].nil?)
+			{
+				echo '<B>Warning:</B> character '.$map[$i].' is missing<BR>';
+				$widths[$i]=$widths['.notdef'];
+			else
+				$widths[$i]=$widths[$map[$i]];
+		end
+	end
+	$fm['Widths']=$widths;
+	return $fm;
+}
+
+function MakeFontDescriptor($fm,$symbolic)
+{
+	#Ascent
+	$asc=($fm['Ascender'].nil? ? $fm['Ascender'] : 1000);
+	$fd="Hash.new('Ascent'=>".$asc;
+	#Descent
+	$desc=($fm['Descender'].nil? ? $fm['Descender'] : -200);
+	$fd<<",'Descent'=>".$desc;
+	#CapHeight
+	if ($fm['CapHeight'].nil?)
+		$ch=$fm['CapHeight'];
+	elsif ($fm['CapXHeight'].nil?)
+		$ch=$fm['CapXHeight'];
+	else
+		$ch=$asc;
+	$fd<<",'CapHeight'=>".$ch;
+	#Flags
+	$flags=0;
+	if ($fm['IsFixedPitch'].nil? and $fm['IsFixedPitch'])
+		$flags+=1<<0;
+	if ($symbolic)
+		$flags+=1<<2;
+	if (!$symbolic)
+		$flags+=1<<5;
+	if ($fm['ItalicAngle'].nil? and $fm['ItalicAngle']!=0)
+		$flags+=1<<6;
+	$fd<<",'Flags'=>".$flags;
+	#FontBBox
+	if ($fm['FontBBox'].nil?)
+		$fbb=$fm['FontBBox'];
+	else
+		$fbb=Hash.new(0,$des-100,1000,$asc+100);
+	$fd<<",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'";
+	#ItalicAngle
+	$ia=($fm['ItalicAngle'].nil? ? $fm['ItalicAngle'] : 0);
+	$fd<<",'ItalicAngle'=>".$ia;
+	#StemV
+	if ($fm['StdVW'].nil?)
+		$stemv=$fm['StdVW'];
+	elsif ($fm['Weight'].nil? and eregi('(bold|black)',$fm['Weight']))
+		$stemv=120;
+	else
+		$stemv=70;
+	$fd<<",'StemV'=>".$stemv;
+	#MissingWidth
+	if ($fm['MissingWidth'].nil?)
+		$fd<<",'MissingWidth'=>".$fm['MissingWidth'];
+	$fd<<')';
+	return $fd;
+}
+
+function MakeWidthArray($fm)
+{
+	#Make character width array
+	$s="Hash.new(\n\t";
+	$cw=$fm['Widths'];
+	for($i=0;$i<=255;$i++)
+	{
+		if ($i.chr=="'")
+			$s<<"'\\''";
+		elsif ($i.chr=="\\")
+			$s<<"'\\\\'";
+		elsif ($i>=32 and $i<=126)
+			$s<<"'".$i.chr."'";
+		else
+			$s<<"$i.chr";
+		$s<<'=>'.$fm['Widths'][$i];
+		if ($i<255)
+			$s<<',';
+		if (($i+1)%22==0)
+			$s<<"\n\t";
+	end
+	$s<<')';
+	return $s;
+}
+
+function MakeFontEncoding($map)
+{
+	#Build differences from reference encoding
+	$ref=ReadMap('cp1252');
+	$s='';
+	$last=0;
+	for($i=32;$i<=255;$i++)
+	{
+		if ($map[$i]!=$ref[$i])
+		{
+			if ($i!=$last+1)
+				$s<<$i.' ';
+			$last=$i;
+			$s<<'/'.$map[$i].' ';
+		end
+	end
+	return rtrim($s);
+}
+
+function SaveToFile($file,$s,$mode='t')
+{
+	$f=fopen($file,'w'.$mode);
+	if (!$f)
+		die('Can\'t write to file '.$file);
+	fwrite($f,$s,$s.length);
+	fclose($f);
+}
+
+function ReadShort($f)
+{
+	$a=unpack('n1n',fread($f,2));
+	return $a['n'];
+}
+
+function ReadLong($f)
+{
+	$a=unpack('N1N',fread($f,4));
+	return $a['N'];
+}
+
+function CheckTTF($file)
+{
+	#Check if font license allows embedding
+	$f=fopen($file,'rb');
+	if (!$f)
+		die('<B>Error:</B> Can\'t open '.$file);
+	#Extract number of tables
+	fseek($f,4,SEEK_CUR);
+	$nb=ReadShort($f);
+	fseek($f,6,SEEK_CUR);
+	#Seek OS/2 table
+	$found=false;
+	for($i=0;$i<$nb;$i++)
+	{
+		if (fread($f,4)=='OS/2')
+		{
+			$found=true;
+			break;
+		end
+		fseek($f,12,SEEK_CUR);
+	end
+	if (!$found)
+	{
+		fclose($f);
+		return;
+	end
+	fseek($f,4,SEEK_CUR);
+	$offset=ReadLong($f);
+	fseek($f,$offset,SEEK_SET);
+	#Extract fsType flags
+	fseek($f,8,SEEK_CUR);
+	$fsType=ReadShort($f);
+	$rl=($fsType & 0x02)!=0;
+	$pp=($fsType & 0x04)!=0;
+	$e=($fsType & 0x08)!=0;
+	fclose($f);
+	if ($rl and !$pp and !$e)
+		echo '<B>Warning:</B> font license does not allow embedding';
+}
+
+#*****************************************************************************
+# $fontfile : chemin du fichier TTF (ou chaîne vide si pas d'incorporation)   #
+# $afmfile :  chemin du fichier AFM                                           #
+# $enc :      encodage (ou chaîne vide si la police est symbolique)           #
+# $patch :    patch optionnel pour l'encodage                                 #
+# $type :     type de la police si $fontfile est vide                         #
+******************************************************************************#
+function MakeFont($fontfile,$afmfile,$enc='cp1252',$patch=Hash.new(),$type='TrueType')
+{
+	#Generate a font definition file
+	set_magic_quotes_runtime(0);
+	ini_set('auto_detect_line_endings','1');
+	if ($enc)
+	{
+		$map=ReadMap($enc);
+		foreach($patch as $cc=>$gn)
+			$map[$cc]=$gn;
+	end
+	else
+		$map = []
+	if (!file_exists($afmfile))
+		die('<B>Error:</B> AFM file not found: '.$afmfile);
+	$fm=ReadAFM($afmfile,$map);
+	if ($enc)
+		$diff=MakeFontEncoding($map);
+	else
+		$diff='';
+	$fd=MakeFontDescriptor($fm,$map.empty?);
+	#Find font type
+	if ($fontfile)
+	{
+		$ext=strtolower(substr($fontfile,-3));
+		if ($ext=='ttf')
+			$type='TrueType';
+		elsif ($ext=='pfb')
+			$type='Type1';
+		else
+			die('<B>Error:</B> unrecognized font file extension: '.$ext);
+	end
+	else
+	{
+		if ($type!='TrueType' and $type!='Type1')
+			die('<B>Error:</B> incorrect font type: '.$type);
+	end
+	#Start generation
+	$s=''."\n";
+	$s<<'$type=\''.$type."';\n";
+	$s<<'$name=\''.$fm['FontName']."';\n";
+	$s<<'$desc='.$fd.";\n";
+	if (!$fm['UnderlinePosition'].nil?)
+		$fm['UnderlinePosition']=-100;
+	if (!$fm['UnderlineThickness'].nil?)
+		$fm['UnderlineThickness']=50;
+	$s<<'$up='.$fm['UnderlinePosition'].";\n";
+	$s<<'$ut='.$fm['UnderlineThickness'].";\n";
+	$w=MakeWidthArray($fm);
+	$s<<'$cw='.$w.";\n";
+	$s<<'$enc=\''.$enc."';\n";
+	$s<<'$diff=\''.$diff."';\n";
+	$basename=substr(basename($afmfile),0,-4);
+	if ($fontfile)
+	{
+		#Embedded font
+		if (!file_exists($fontfile))
+			die('<B>Error:</B> font file not found: '.$fontfile);
+		if ($type=='TrueType')
+			CheckTTF($fontfile);
+		$f=fopen($fontfile,'rb');
+		if (!$f)
+			die('<B>Error:</B> Can\'t open '.$fontfile);
+		$file=fread($f,filesize($fontfile));
+		fclose($f);
+		if ($type=='Type1')
+		{
+			#Find first two sections and discard third one
+			$header=($file[0][0]==128);
+			if ($header)
+			{
+				#Strip first binary header
+				$file=substr($file,6);
+			end
+			$pos=$file.include?('eexec');
+			if (!$pos)
+				die('<B>Error:</B> font file does not seem to be valid Type1');
+			$size1=$pos+6;
+			if ($header and ?($file{$size1})==128)
+			{
+				#Strip second binary header
+				$file=substr($file,0,$size1).substr($file,$size1+6);
+			end
+			$pos=$file.include?('00000000');
+			if (!$pos)
+				die('<B>Error:</B> font file does not seem to be valid Type1');
+			$size2=$pos-$size1;
+			$file=substr($file,0,$size1+$size2);
+		end
+		if (respond_to('gzcompress'))
+		{
+			$cmp=$basename.'.z';
+			SaveToFile($cmp,gzcompress($file),'b');
+			$s<<'$file=\''.$cmp."';\n";
+			echo 'Font file compressed ('.$cmp.')<BR>';
+		else
+		{
+			$s<<'$file=\''.basename($fontfile)."';\n";
+			echo '<B>Notice:</B> font file could not be compressed (zlib extension not available)<BR>';
+		end
+		if ($type=='Type1')
+		{
+			$s<<'$size1='.$size1.";\n";
+			$s<<'$size2='.$size2.";\n";
+		else
+			$s<<'$originalsize='.filesize($fontfile).";\n";
+	end
+	else
+	{
+		#Not embedded font
+		$s<<'$file='."'';\n";
+	end
+	$s<<"\n";
+	SaveToFile($basename.'.rb',$s);
+	echo 'Font definition file generated ('.$basename.'.rb'.')<BR>';
+}
+