Project import generated by Copybara.

GitOrigin-RevId: 63746295f1a5ab5a619056791995793d65529e62
diff --git a/src/lib/fpdf/makefont/makefont.php b/src/lib/fpdf/makefont/makefont.php
new file mode 100644
index 0000000..fbe8dcf
--- /dev/null
+++ b/src/lib/fpdf/makefont/makefont.php
@@ -0,0 +1,447 @@
+<?php

+/*******************************************************************************

+* Utility to generate font definition files                                    *

+*                                                                              *

+* Version: 1.31                                                                *

+* Date:    2019-12-07                                                          *

+* Author:  Olivier PLATHEY                                                     *

+*******************************************************************************/

+

+require('ttfparser.php');

+

+function Message($txt, $severity='')

+{

+	if(PHP_SAPI=='cli')

+	{

+		if($severity)

+			echo "$severity: ";

+		echo "$txt\n";

+	}

+	else

+	{

+		if($severity)

+			echo "<b>$severity</b>: ";

+		echo "$txt<br>";

+	}

+}

+

+function Notice($txt)

+{

+	Message($txt, 'Notice');

+}

+

+function Warning($txt)

+{

+	Message($txt, 'Warning');

+}

+

+function Error($txt)

+{

+	Message($txt, 'Error');

+	exit;

+}

+

+function LoadMap($enc)

+{

+	$file = dirname(__FILE__).'/'.strtolower($enc).'.map';

+	$a = file($file);

+	if(empty($a))

+		Error('Encoding not found: '.$enc);

+	$map = array_fill(0, 256, array('uv'=>-1, 'name'=>'.notdef'));

+	foreach($a as $line)

+	{

+		$e = explode(' ', rtrim($line));

+		$c = hexdec(substr($e[0],1));

+		$uv = hexdec(substr($e[1],2));

+		$name = $e[2];

+		$map[$c] = array('uv'=>$uv, 'name'=>$name);

+	}

+	return $map;

+}

+

+function GetInfoFromTrueType($file, $embed, $subset, $map)

+{

+	// Return information from a TrueType font

+	try

+	{

+		$ttf = new TTFParser($file);

+		$ttf->Parse();

+	}

+	catch(Exception $e)

+	{

+		Error($e->getMessage());

+	}

+	if($embed)

+	{

+		if(!$ttf->embeddable)

+			Error('Font license does not allow embedding');

+		if($subset)

+		{

+			$chars = array();

+			foreach($map as $v)

+			{

+				if($v['name']!='.notdef')

+					$chars[] = $v['uv'];

+			}

+			$ttf->Subset($chars);

+			$info['Data'] = $ttf->Build();

+		}

+		else

+			$info['Data'] = file_get_contents($file);

+		$info['OriginalSize'] = strlen($info['Data']);

+	}

+	$k = 1000/$ttf->unitsPerEm;

+	$info['FontName'] = $ttf->postScriptName;

+	$info['Bold'] = $ttf->bold;

+	$info['ItalicAngle'] = $ttf->italicAngle;

+	$info['IsFixedPitch'] = $ttf->isFixedPitch;

+	$info['Ascender'] = round($k*$ttf->typoAscender);

+	$info['Descender'] = round($k*$ttf->typoDescender);

+	$info['UnderlineThickness'] = round($k*$ttf->underlineThickness);

+	$info['UnderlinePosition'] = round($k*$ttf->underlinePosition);

+	$info['FontBBox'] = array(round($k*$ttf->xMin), round($k*$ttf->yMin), round($k*$ttf->xMax), round($k*$ttf->yMax));

+	$info['CapHeight'] = round($k*$ttf->capHeight);

+	$info['MissingWidth'] = round($k*$ttf->glyphs[0]['w']);

+	$widths = array_fill(0, 256, $info['MissingWidth']);

+	foreach($map as $c=>$v)

+	{

+		if($v['name']!='.notdef')

+		{

+			if(isset($ttf->chars[$v['uv']]))

+			{

+				$id = $ttf->chars[$v['uv']];

+				$w = $ttf->glyphs[$id]['w'];

+				$widths[$c] = round($k*$w);

+			}

+			else

+				Warning('Character '.$v['name'].' is missing');

+		}

+	}

+	$info['Widths'] = $widths;

+	return $info;

+}

+

+function GetInfoFromType1($file, $embed, $map)

+{

+	// Return information from a Type1 font

+	if($embed)

+	{

+		$f = fopen($file, 'rb');

+		if(!$f)

+			Error('Can\'t open font file');

+		// Read first segment

+		$a = unpack('Cmarker/Ctype/Vsize', fread($f,6));

+		if($a['marker']!=128)

+			Error('Font file is not a valid binary Type1');

+		$size1 = $a['size'];

+		$data = fread($f, $size1);

+		// Read second segment

+		$a = unpack('Cmarker/Ctype/Vsize', fread($f,6));

+		if($a['marker']!=128)

+			Error('Font file is not a valid binary Type1');

+		$size2 = $a['size'];

+		$data .= fread($f, $size2);

+		fclose($f);

+		$info['Data'] = $data;

+		$info['Size1'] = $size1;

+		$info['Size2'] = $size2;

+	}

+

+	$afm = substr($file, 0, -3).'afm';

+	if(!file_exists($afm))

+		Error('AFM font file not found: '.$afm);

+	$a = file($afm);

+	if(empty($a))

+		Error('AFM file empty or not readable');

+	foreach($a as $line)

+	{

+		$e = explode(' ', rtrim($line));

+		if(count($e)<2)

+			continue;

+		$entry = $e[0];

+		if($entry=='C')

+		{

+			$w = $e[4];

+			$name = $e[7];

+			$cw[$name] = $w;

+		}

+		elseif($entry=='FontName')

+			$info['FontName'] = $e[1];

+		elseif($entry=='Weight')

+			$info['Weight'] = $e[1];

+		elseif($entry=='ItalicAngle')

+			$info['ItalicAngle'] = (int)$e[1];

+		elseif($entry=='Ascender')

+			$info['Ascender'] = (int)$e[1];

+		elseif($entry=='Descender')

+			$info['Descender'] = (int)$e[1];

+		elseif($entry=='UnderlineThickness')

+			$info['UnderlineThickness'] = (int)$e[1];

+		elseif($entry=='UnderlinePosition')

+			$info['UnderlinePosition'] = (int)$e[1];

+		elseif($entry=='IsFixedPitch')

+			$info['IsFixedPitch'] = ($e[1]=='true');

+		elseif($entry=='FontBBox')

+			$info['FontBBox'] = array((int)$e[1], (int)$e[2], (int)$e[3], (int)$e[4]);

+		elseif($entry=='CapHeight')

+			$info['CapHeight'] = (int)$e[1];

+		elseif($entry=='StdVW')

+			$info['StdVW'] = (int)$e[1];

+	}

+

+	if(!isset($info['FontName']))

+		Error('FontName missing in AFM file');

+	if(!isset($info['Ascender']))

+		$info['Ascender'] = $info['FontBBox'][3];

+	if(!isset($info['Descender']))

+		$info['Descender'] = $info['FontBBox'][1];

+	$info['Bold'] = isset($info['Weight']) && preg_match('/bold|black/i', $info['Weight']);

+	if(isset($cw['.notdef']))

+		$info['MissingWidth'] = $cw['.notdef'];

+	else

+		$info['MissingWidth'] = 0;

+	$widths = array_fill(0, 256, $info['MissingWidth']);

+	foreach($map as $c=>$v)

+	{

+		if($v['name']!='.notdef')

+		{

+			if(isset($cw[$v['name']]))

+				$widths[$c] = $cw[$v['name']];

+			else

+				Warning('Character '.$v['name'].' is missing');

+		}

+	}

+	$info['Widths'] = $widths;

+	return $info;

+}

+

+function MakeFontDescriptor($info)

+{

+	// Ascent

+	$fd = "array('Ascent'=>".$info['Ascender'];

+	// Descent

+	$fd .= ",'Descent'=>".$info['Descender'];

+	// CapHeight

+	if(!empty($info['CapHeight']))

+		$fd .= ",'CapHeight'=>".$info['CapHeight'];

+	else

+		$fd .= ",'CapHeight'=>".$info['Ascender'];

+	// Flags

+	$flags = 0;

+	if($info['IsFixedPitch'])

+		$flags += 1<<0;

+	$flags += 1<<5;

+	if($info['ItalicAngle']!=0)

+		$flags += 1<<6;

+	$fd .= ",'Flags'=>".$flags;

+	// FontBBox

+	$fbb = $info['FontBBox'];

+	$fd .= ",'FontBBox'=>'[".$fbb[0].' '.$fbb[1].' '.$fbb[2].' '.$fbb[3]."]'";

+	// ItalicAngle

+	$fd .= ",'ItalicAngle'=>".$info['ItalicAngle'];

+	// StemV

+	if(isset($info['StdVW']))

+		$stemv = $info['StdVW'];

+	elseif($info['Bold'])

+		$stemv = 120;

+	else

+		$stemv = 70;

+	$fd .= ",'StemV'=>".$stemv;

+	// MissingWidth

+	$fd .= ",'MissingWidth'=>".$info['MissingWidth'].')';

+	return $fd;

+}

+

+function MakeWidthArray($widths)

+{

+	$s = "array(\n\t";

+	for($c=0;$c<=255;$c++)

+	{

+		if(chr($c)=="'")

+			$s .= "'\\''";

+		elseif(chr($c)=="\\")

+			$s .= "'\\\\'";

+		elseif($c>=32 && $c<=126)

+			$s .= "'".chr($c)."'";

+		else

+			$s .= "chr($c)";

+		$s .= '=>'.$widths[$c];

+		if($c<255)

+			$s .= ',';

+		if(($c+1)%22==0)

+			$s .= "\n\t";

+	}

+	$s .= ')';

+	return $s;

+}

+

+function MakeFontEncoding($map)

+{

+	// Build differences from reference encoding

+	$ref = LoadMap('cp1252');

+	$s = '';

+	$last = 0;

+	for($c=32;$c<=255;$c++)

+	{

+		if($map[$c]['name']!=$ref[$c]['name'])

+		{

+			if($c!=$last+1)

+				$s .= $c.' ';

+			$last = $c;

+			$s .= '/'.$map[$c]['name'].' ';

+		}

+	}

+	return rtrim($s);

+}

+

+function MakeUnicodeArray($map)

+{

+	// Build mapping to Unicode values

+	$ranges = array();

+	foreach($map as $c=>$v)

+	{

+		$uv = $v['uv'];

+		if($uv!=-1)

+		{

+			if(isset($range))

+			{

+				if($c==$range[1]+1 && $uv==$range[3]+1)

+				{

+					$range[1]++;

+					$range[3]++;

+				}

+				else

+				{

+					$ranges[] = $range;

+					$range = array($c, $c, $uv, $uv);

+				}

+			}

+			else

+				$range = array($c, $c, $uv, $uv);

+		}

+	}

+	$ranges[] = $range;

+

+	foreach($ranges as $range)

+	{

+		if(isset($s))

+			$s .= ',';

+		else

+			$s = 'array(';

+		$s .= $range[0].'=>';

+		$nb = $range[1]-$range[0]+1;

+		if($nb>1)

+			$s .= 'array('.$range[2].','.$nb.')';

+		else

+			$s .= $range[2];

+	}

+	$s .= ')';

+	return $s;

+}

+

+function SaveToFile($file, $s, $mode)

+{

+	$f = fopen($file, 'w'.$mode);

+	if(!$f)

+		Error('Can\'t write to file '.$file);

+	fwrite($f, $s);

+	fclose($f);

+}

+

+function MakeDefinitionFile($file, $type, $enc, $embed, $subset, $map, $info)

+{

+	$s = "<?php\n";

+	$s .= '$type = \''.$type."';\n";

+	$s .= '$name = \''.$info['FontName']."';\n";

+	$s .= '$desc = '.MakeFontDescriptor($info).";\n";

+	$s .= '$up = '.$info['UnderlinePosition'].";\n";

+	$s .= '$ut = '.$info['UnderlineThickness'].";\n";

+	$s .= '$cw = '.MakeWidthArray($info['Widths']).";\n";

+	$s .= '$enc = \''.$enc."';\n";

+	$diff = MakeFontEncoding($map);

+	if($diff)

+		$s .= '$diff = \''.$diff."';\n";

+	$s .= '$uv = '.MakeUnicodeArray($map).";\n";

+	if($embed)

+	{

+		$s .= '$file = \''.$info['File']."';\n";

+		if($type=='Type1')

+		{

+			$s .= '$size1 = '.$info['Size1'].";\n";

+			$s .= '$size2 = '.$info['Size2'].";\n";

+		}

+		else

+		{

+			$s .= '$originalsize = '.$info['OriginalSize'].";\n";

+			if($subset)

+				$s .= "\$subsetted = true;\n";

+		}

+	}

+	$s .= "?>\n";

+	SaveToFile($file, $s, 't');

+}

+

+function MakeFont($fontfile, $enc='cp1252', $embed=true, $subset=true)

+{

+	// Generate a font definition file

+	if(!file_exists($fontfile))

+		Error('Font file not found: '.$fontfile);

+	$ext = strtolower(substr($fontfile,-3));

+	if($ext=='ttf' || $ext=='otf')

+		$type = 'TrueType';

+	elseif($ext=='pfb')

+		$type = 'Type1';

+	else

+		Error('Unrecognized font file extension: '.$ext);

+

+	$map = LoadMap($enc);

+

+	if($type=='TrueType')

+		$info = GetInfoFromTrueType($fontfile, $embed, $subset, $map);

+	else

+		$info = GetInfoFromType1($fontfile, $embed, $map);

+

+	$basename = substr(basename($fontfile), 0, -4);

+	if($embed)

+	{

+		if(function_exists('gzcompress'))

+		{

+			$file = $basename.'.z';

+			SaveToFile($file, gzcompress($info['Data']), 'b');

+			$info['File'] = $file;

+			Message('Font file compressed: '.$file);

+		}

+		else

+		{

+			$info['File'] = basename($fontfile);

+			$subset = false;

+			Notice('Font file could not be compressed (zlib extension not available)');

+		}

+	}

+

+	MakeDefinitionFile($basename.'.php', $type, $enc, $embed, $subset, $map, $info);

+	Message('Font definition file generated: '.$basename.'.php');

+}

+

+if(PHP_SAPI=='cli')

+{

+	// Command-line interface

+	ini_set('log_errors', '0');

+	if($argc==1)

+		die("Usage: php makefont.php fontfile [encoding] [embed] [subset]\n");

+	$fontfile = $argv[1];

+	if($argc>=3)

+		$enc = $argv[2];

+	else

+		$enc = 'cp1252';

+	if($argc>=4)

+		$embed = ($argv[3]=='true' || $argv[3]=='1');

+	else

+		$embed = true;

+	if($argc>=5)

+		$subset = ($argv[4]=='true' || $argv[4]=='1');

+	else

+		$subset = true;

+	MakeFont($fontfile, $enc, $embed, $subset);

+}

+?>