#!/usr/bin/env php * @copyright 2011-2026 Nicola Asuni - Tecnick.com LTD * @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE) * @link https://github.com/tecnickcom/tc-lib-pdf-font * * This file is part of tc-lib-pdf-font software library. * * Command-line tool to convert fonts data for the tc-lib-pdf-font library. */ if (\php_sapi_name() != 'cli') { \fwrite(STDERR, 'You need to run this command from console.'."\n"); exit(1); } /** * Display help guide for this command. */ function showHelp() { $help = << \dirname(__DIR__) . '/target/fonts/', 'type' => '', 'encoding' => '', 'flags' => 32, 'platform_id' => 3, 'encoding_id' => 1, 'linked' => false ); // short input options $sopt = 't:e:f:o:p:n:li:h'; // long input options $lopt = array( 'outpath:', 'type:', 'encoding:', 'flags:', 'platform_id:', 'encoding_id:', 'linked', 'fonts:', 'help' ); // parse input options $inopt = \getopt($sopt, $lopt); // import options (with some sanitization) foreach ($inopt as $opt => $val) { switch ($opt) { case 'o': case 'outpath': // Keep the raw value when the directory does not exist yet: // realpath() returns false for a missing path and would // otherwise collapse the output path to '/'. The directory is // created and the path normalized further below. $resolved = \realpath($val); $options['outpath'] = ($resolved !== false) ? $resolved : $val; if (\substr($options['outpath'], -1) != '/') { $options['outpath'] .= '/'; } break; case 't': case 'type': if (\in_array($val, array('TrueTypeUnicode', 'TrueType', 'Type1', 'CID0JP', 'CID0KR', 'CID0CS', 'CID0CT'))) { $options['type'] = $val; } break; case 'e': case 'encoding': $options['encoding'] = $val; break; case 'f': case 'flags': $options['flags'] = \intval($val); break; case 'p': case 'platform_id': $options['platform_id'] = \min(\max(1, \intval($val)), 3); break; case 'n': case 'encoding_id': $options['encoding_id'] = \min(\max(0, \intval($val)), 10); break; case 'l': case 'linked': $options['linked'] = true; break; case 'i': case 'fonts': $options['fonts'] = \explode(',', $val); break; case 'h': case 'help': default: showHelp(); break; } } // check input values if (!is_dir($options['outpath'])) { \mkdir($options['outpath'], 0755, true); } if (!is_dir($options['outpath']) || !\is_writable($options['outpath'])) { \fwrite(STDERR, 'ERROR: Can\'t write to '.$options['outpath']."\n\n"); exit(2); } // the directory now exists: normalize to an absolute path with trailing slash $options['outpath'] = \realpath($options['outpath']) . '/'; if (empty($options['fonts'])) { \fwrite(STDERR, 'ERROR: missing input fonts (try --help for usage)'."\n\n"); exit(3); } \fwrite(STDOUT, "\n".'>>> Converting fonts:'."\n".'*** Output directory set to '.$options['outpath']."\n"); // count conversions $convert_errors = 0; $convert_success = 0; // Locate the Composer autoloader, supporting both a standalone checkout // (vendor inside the project root) and installation as a dependency // (autoloader at the top level of the host project). $autoloadFound = false; foreach ( array( \dirname(__DIR__) . '/vendor/autoload.php', // standalone repository checkout \dirname(__DIR__, 4) . '/vendor/autoload.php', // installed under /vendor/tecnickcom/tc-lib-pdf-font ) as $autoloadFile ) { if (\is_file($autoloadFile)) { require_once $autoloadFile; $autoloadFound = true; break; } } if (!$autoloadFound) { \fwrite(STDERR, 'ERROR: Composer autoloader not found. Run "composer install" first.'."\n\n"); exit(5); } foreach ($options['fonts'] as $font) { try { $fontFile = realpath($font); if ($fontFile === false) { throw new \Exception('Invalid font file path: ' . $font); } $allowedPaths = \array_values(\array_unique(\array_filter(array_map( static fn (string $path): string => rtrim($path, '/\\'), \array_merge( \Com\Tecnick\Pdf\Font\FontPaths::buildAllowedPaths(), [\dirname($fontFile), $options['outpath']] ) )))); $fileHelper = new \Com\Tecnick\File\File(allowedPaths: $allowedPaths); $import = new \Com\Tecnick\Pdf\Font\Import( $fontFile, $options['outpath'], $options['type'], $options['encoding'], $options['flags'], $options['platform_id'], $options['encoding_id'], $options['linked'], $fileHelper ); $fontname = $import->getFontName(); \fwrite(STDOUT, "\033[32m".'+++ OK : '.$font.' added as '.$fontname."\033[m\n"); ++$convert_success; } catch (\Exception $exc) { ++$convert_errors; \fwrite(STDERR, "\033[31m".'--- ERROR: can\'t add '.$font."\n ".$exc->getMessage()."\033[m\n"); } } $endmsg = '>>> PROCESS COMPLETED: '.$convert_success.' CONVERTED FONT(S), '.$convert_errors.' ERROR(S)!'."\n\n"; if ($convert_errors > 0) { \fwrite(STDERR, "\033[31m".$endmsg.'ERROR'."\033[m"); exit(4); } \fwrite(STDOUT, "\033[32m".$endmsg."\033[m"); exit(0);