Your project should not change PHP configuration dynamically
- Read doc
- Productivity
- Major
More information: https://insight.symfony.com/what-we-analyse/php.dynamically_change_configuration
- Message('Font definition file generated: ' . $basename . '.php');
- }
- if (\PHP_SAPI === 'cli') {
- // Command-line interface
- \ini_set('log_errors', '0');
- if (1 === $argc) {
- exit("Usage: php makefont.php fontfile [encoding] [embed] [subset]\n");
- }
- $fontfile = $argv[1];
- if ($argc >= 3) {
Your project uses discouraged functions to kill scripts 2
- Read doc
- Reliability
- Major
More information: https://insight.symfony.com/what-we-analyse/php.use_exit_function
- }
- function Error($txt): void
- {
- Message($txt, 'Error');
- exit;
- }
- function LoadMap($enc)
- {
- $file = __DIR__ . '/' . \strtolower($enc) . '.map';
- if (\PHP_SAPI === 'cli') {
- // Command-line interface
- \ini_set('log_errors', '0');
- if (1 === $argc) {
- exit("Usage: php makefont.php fontfile [encoding] [embed] [subset]\n");
- }
- $fontfile = $argv[1];
- if ($argc >= 3) {
- $enc = $argv[2];
- } else {
Your project should not use too long PHP classes
- Read doc
- Productivity
- Major
More information: https://insight.symfony.com/what-we-analyse/php.class_too_long
- fpdf\PdfDocument is 2123 lines long
- ttfparser is 851 lines long
Your project should not use global variables or functions 14
- Read doc
- Reliability
- Minor
More information: https://insight.symfony.com/what-we-analyse/php.use_global_variable_or_function
- * Author: Olivier PLATHEY *
- *******************************************************************************/
- require 'ttfparser.php';
- function Message($txt, $severity = ''): void
- {
- if (\PHP_SAPI === 'cli') {
- if ($severity) {
- echo "$severity: ";
- }
- }
- echo "$txt<br>";
- }
- }
- function Notice($txt): void
- {
- Message($txt, 'Notice');
- }
- function Warning($txt): void
- function Notice($txt): void
- {
- Message($txt, 'Notice');
- }
- function Warning($txt): void
- {
- Message($txt, 'Warning');
- }
- function Error($txt): void
- function Warning($txt): void
- {
- Message($txt, 'Warning');
- }
- function Error($txt): void
- {
- Message($txt, 'Error');
- exit;
- }
- {
- Message($txt, 'Error');
- exit;
- }
- function LoadMap($enc)
- {
- $file = __DIR__ . '/' . \strtolower($enc) . '.map';
- $a = \file($file);
- if (empty($a)) {
- Error('Encoding not found: ' . $enc);
- }
- return $map;
- }
- function GetInfoFromTrueType($file, $embed, $subset, $map)
- {
- // Return information from a TrueType font
- try {
- $ttf = new TTFParser($file);
- $ttf->Parse();
- $info['Widths'] = $widths;
- return $info;
- }
- function GetInfoFromType1($file, $embed, $map)
- {
- // Return information from a Type1 font
- if ($embed) {
- $f = \fopen($file, 'r');
- if (!$f) {
- $info['Widths'] = $widths;
- return $info;
- }
- function MakeFontDescriptor($info)
- {
- // Ascent
- $fd = "array('Ascent'=>" . $info['Ascender'];
- // Descent
- $fd .= ",'Descent'=>" . $info['Descender'];
- $fd .= ",'MissingWidth'=>" . $info['MissingWidth'] . ')';
- return $fd;
- }
- function MakeWidthArray($widths)
- {
- $s = "array(\n\t";
- for ($c = 0; $c <= 255; ++$c) {
- if ("'" === \chr($c)) {
- $s .= "'\\''";
- $s .= ')';
- return $s;
- }
- function MakeFontEncoding($map)
- {
- // Build differences from reference encoding
- $ref = LoadMap('cp1252');
- $s = '';
- $last = 0;
- }
- return \rtrim($s);
- }
- function MakeUnicodeArray($map)
- {
- // Build mapping to Unicode values
- $ranges = [];
- foreach ($map as $c => $v) {
- $uv = $v['uv'];
- $s .= ')';
- return $s;
- }
- function SaveToFile($file, $s, $mode): void
- {
- $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): void
- {
- $s = "<?php\n";
- $s .= '$type = \'' . $type . "';\n";
- $s .= '$name = \'' . $info['FontName'] . "';\n";
- $s .= '$desc = ' . MakeFontDescriptor($info) . ";\n";
- }
- $s .= "?>\n";
- SaveToFile($file, $s, 't');
- }
- function MakeFont($fontfile, $enc = 'cp1252', $embed = true, $subset = true): void
- {
- // Generate a font definition file
- if (!\file_exists($fontfile)) {
- Error('Font file not found: ' . $fontfile);
- }
Your project should not contain duplicated code 4
- Read doc
- Productivity
- Minor
More information: https://insight.symfony.com/what-we-analyse/php.duplicated_code
- <?php
- $type = 'Core';
- $name = 'Courier';
- $up = -100;
- $ut = 50;
- for($i=0;$i<=255;$i++)
- $cw[chr($i)] = 600;
- $enc = 'cp1252';
- $uv = array(0=>array(0,128),128=>8364,130=>8218,131=>402,132=>8222,133=>8230,134=>array(8224,2),136=>710,137=>8240,138=>352,139=>8249,140=>338,142=>381,145=>array(8216,2),147=>array(8220,2),149=>8226,150=>array(8211,2),152=>732,153=>8482,154=>353,155=>8250,156=>339,158=>382,159=>376,160=>array(160,96));
- <?php
- $type = 'Core';
- $name = 'Helvetica';
- $up = -100;
- $ut = 50;
- $cw = array(
- chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
- chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
- ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
- <?php
- $type = 'Core';
- $name = 'Helvetica';
- $up = -100;
- $ut = 50;
- $cw = array(
- chr(0)=>278,chr(1)=>278,chr(2)=>278,chr(3)=>278,chr(4)=>278,chr(5)=>278,chr(6)=>278,chr(7)=>278,chr(8)=>278,chr(9)=>278,chr(10)=>278,chr(11)=>278,chr(12)=>278,chr(13)=>278,chr(14)=>278,chr(15)=>278,chr(16)=>278,chr(17)=>278,chr(18)=>278,chr(19)=>278,chr(20)=>278,chr(21)=>278,
- chr(22)=>278,chr(23)=>278,chr(24)=>278,chr(25)=>278,chr(26)=>278,chr(27)=>278,chr(28)=>278,chr(29)=>278,chr(30)=>278,chr(31)=>278,' '=>278,'!'=>278,'"'=>355,'#'=>556,'$'=>556,'%'=>889,'&'=>667,'\''=>191,'('=>333,')'=>333,'*'=>389,'+'=>584,
- ','=>278,'-'=>333,'.'=>278,'/'=>278,'0'=>556,'1'=>556,'2'=>556,'3'=>556,'4'=>556,'5'=>556,'6'=>556,'7'=>556,'8'=>556,'9'=>556,':'=>278,';'=>278,'<'=>584,'='=>584,'>'=>584,'?'=>556,'@'=>1015,'A'=>667,
- <?php
- $type = 'Core';
- $name = 'Symbol';
- $up = -100;
- $ut = 50;
- $cw = array(
- chr(0)=>250,chr(1)=>250,chr(2)=>250,chr(3)=>250,chr(4)=>250,chr(5)=>250,chr(6)=>250,chr(7)=>250,chr(8)=>250,chr(9)=>250,chr(10)=>250,chr(11)=>250,chr(12)=>250,chr(13)=>250,chr(14)=>250,chr(15)=>250,chr(16)=>250,chr(17)=>250,chr(18)=>250,chr(19)=>250,chr(20)=>250,chr(21)=>250,
- chr(22)=>250,chr(23)=>250,chr(24)=>250,chr(25)=>250,chr(26)=>250,chr(27)=>250,chr(28)=>250,chr(29)=>250,chr(30)=>250,chr(31)=>250,' '=>250,'!'=>333,'"'=>713,'#'=>500,'$'=>549,'%'=>833,'&'=>778,'\''=>439,'('=>333,')'=>333,'*'=>500,'+'=>549,
- ','=>250,'-'=>549,'.'=>250,'/'=>278,'0'=>500,'1'=>500,'2'=>500,'3'=>500,'4'=>500,'5'=>500,'6'=>500,'7'=>500,'8'=>500,'9'=>500,':'=>278,';'=>278,'<'=>549,'='=>549,'>'=>549,'?'=>444,'@'=>549,'A'=>722,
The code of your project must follow PSR-1 basic coding standard 34
- Read doc
- Productivity
- Minor
More information: https://insight.symfony.com/what-we-analyse/php.psr1
- * Version: 1.11 *
- * Date: 2021-04-18 *
- * Author: Olivier PLATHEY *
- *******************************************************************************/
- class ttfparser
- {
- public $bold;
- public $capHeight;
- public $chars;
- public $embeddable;
- if (\is_resource($this->f)) {
- \fclose($this->f);
- }
- }
- public function AddGlyph($id): void
- {
- if (!isset($this->glyphs[$id]['ssid'])) {
- $this->glyphs[$id]['ssid'] = \count($this->subsettedGlyphs);
- $this->subsettedGlyphs[] = $id;
- if (isset($this->glyphs[$id]['components'])) {
- }
- }
- }
- }
- public function Build()
- {
- $this->BuildCmap();
- $this->BuildHhea();
- $this->BuildHmtx();
- $this->BuildLoca();
- $this->BuildPost();
- return $this->BuildFont();
- }
- public function BuildCmap(): void
- {
- if (!isset($this->subsettedChars)) {
- return;
- }
- $data .= \pack('nnn', 4, 6 + \strlen($cmap), 0); // format, length, language
- $data .= $cmap;
- $this->SetTable('cmap', $data);
- }
- public function BuildFont()
- {
- $tags = [];
- foreach (['cmap', 'cvt ', 'fpgm', 'glyf', 'head', 'hhea', 'hmtx', 'loca', 'maxp', 'name', 'post', 'prep'] as $tag) {
- if (isset($this->tables[$tag])) {
- $tags[] = $tag;
- }
- return $font;
- }
- public function BuildGlyf(): void
- {
- $tableOffset = $this->tables['glyf']['offset'];
- $data = '';
- foreach ($this->subsettedGlyphs as $id) {
- $glyph = $this->glyphs[$id];
- $data .= $glyph_data;
- }
- $this->SetTable('glyf', $data);
- }
- public function BuildHhea(): void
- {
- $this->LoadTable('hhea');
- $numberOfHMetrics = \count($this->subsettedGlyphs);
- $data = \substr_replace($this->tables['hhea']['data'], \pack('n', $numberOfHMetrics), 4 + 15 * 2, 2);
- $this->SetTable('hhea', $data);
- $numberOfHMetrics = \count($this->subsettedGlyphs);
- $data = \substr_replace($this->tables['hhea']['data'], \pack('n', $numberOfHMetrics), 4 + 15 * 2, 2);
- $this->SetTable('hhea', $data);
- }
- public function BuildHmtx(): void
- {
- $data = '';
- foreach ($this->subsettedGlyphs as $id) {
- $glyph = $this->glyphs[$id];
- $data .= \pack('nn', $glyph['w'], $glyph['lsb']);
- $data .= \pack('nn', $glyph['w'], $glyph['lsb']);
- }
- $this->SetTable('hmtx', $data);
- }
- public function BuildLoca(): void
- {
- $data = '';
- $offset = 0;
- foreach ($this->subsettedGlyphs as $id) {
- if (0 === $this->indexToLocFormat) {
- $data .= \pack('N', $offset);
- }
- $this->SetTable('loca', $data);
- }
- public function BuildMaxp(): void
- {
- $this->LoadTable('maxp');
- $numGlyphs = \count($this->subsettedGlyphs);
- $data = \substr_replace($this->tables['maxp']['data'], \pack('n', $numGlyphs), 4, 2);
- $this->SetTable('maxp', $data);
- $numGlyphs = \count($this->subsettedGlyphs);
- $data = \substr_replace($this->tables['maxp']['data'], \pack('n', $numGlyphs), 4, 2);
- $this->SetTable('maxp', $data);
- }
- public function BuildPost(): void
- {
- $this->Seek('post');
- if ($this->glyphNames) {
- // Version 2.0
- $numberOfGlyphs = \count($this->subsettedGlyphs);
- $data .= $this->Read(4 + 2 * 2 + 5 * 4);
- }
- $this->SetTable('post', $data);
- }
- public function CheckSum($s)
- {
- $n = \strlen($s);
- $high = 0;
- $low = 0;
- for ($i = 0; $i < $n; $i += 4) {
- }
- return \pack('nn', $high + ($low >> 16), $low);
- }
- public function Error($msg): void
- {
- throw new Exception($msg);
- }
- public function LoadTable($tag): void
- public function Error($msg): void
- {
- throw new Exception($msg);
- }
- public function LoadTable($tag): void
- {
- $this->Seek($tag);
- $length = $this->tables[$tag]['length'];
- $n = $length % 4;
- if ($n > 0) {
- $length += 4 - $n;
- }
- $this->tables[$tag]['data'] = $this->Read($length);
- }
- public function Parse(): void
- {
- $this->ParseOffsetTable();
- $this->ParseHead();
- $this->ParseHhea();
- $this->ParseMaxp();
- $this->ParseName();
- $this->ParseOS2();
- $this->ParsePost();
- }
- public function ParseCmap(): void
- {
- $this->Seek('cmap');
- $this->Skip(2); // version
- $numTables = $this->ReadUShort();
- $offset31 = 0;
- }
- }
- }
- }
- public function ParseGlyf(): void
- {
- $tableOffset = $this->tables['glyf']['offset'];
- foreach ($this->glyphs as &$glyph) {
- if ($glyph['length'] > 0) {
- \fseek($this->f, $tableOffset + $glyph['offset'], \SEEK_SET);
- }
- }
- }
- }
- public function ParseHead(): void
- {
- $this->Seek('head');
- $this->Skip(3 * 4); // version, fontRevision, checkSumAdjustment
- $magicNumber = $this->ReadULong();
- if (0x5F0F3CF5 !== $magicNumber) {
- $this->yMax = $this->ReadShort();
- $this->Skip(3 * 2); // macStyle, lowestRecPPEM, fontDirectionHint
- $this->indexToLocFormat = $this->ReadShort();
- }
- public function ParseHhea(): void
- {
- $this->Seek('hhea');
- $this->Skip(4 + 15 * 2);
- $this->numberOfHMetrics = $this->ReadUShort();
- }
- $this->Seek('hhea');
- $this->Skip(4 + 15 * 2);
- $this->numberOfHMetrics = $this->ReadUShort();
- }
- public function ParseHmtx(): void
- {
- $this->Seek('hmtx');
- $this->glyphs = [];
- for ($i = 0; $i < $this->numberOfHMetrics; ++$i) {
- $advanceWidth = $this->ReadUShort();
- $lsb = $this->ReadShort();
- $this->glyphs[$i] = ['w' => $advanceWidth, 'lsb' => $lsb];
- }
- }
- public function ParseLoca(): void
- {
- $this->Seek('loca');
- $offsets = [];
- if (0 === $this->indexToLocFormat) {
- // Short format
- $this->glyphs[$i]['offset'] = $offsets[$i];
- $this->glyphs[$i]['length'] = $offsets[$i + 1] - $offsets[$i];
- }
- }
- public function ParseMaxp(): void
- {
- $this->Seek('maxp');
- $this->Skip(4);
- $this->numGlyphs = $this->ReadUShort();
- }
- $this->Seek('maxp');
- $this->Skip(4);
- $this->numGlyphs = $this->ReadUShort();
- }
- public function ParseName(): void
- {
- $this->Seek('name');
- $tableOffset = $this->tables['name']['offset'];
- $this->postScriptName = '';
- $this->Skip(2); // format
- if ('' === $this->postScriptName) {
- $this->Error('PostScript name not found');
- }
- }
- public function ParseOffsetTable(): void
- {
- $version = $this->Read(4);
- if ('OTTO' === $version) {
- $this->Error('OpenType fonts based on PostScript outlines are not supported');
- }
- $length = $this->ReadULong();
- $this->tables[$tag] = ['offset' => $offset, 'length' => $length, 'checkSum' => $checkSum];
- }
- }
- public function ParseOS2(): void
- {
- $this->Seek('OS/2');
- $version = $this->ReadUShort();
- $this->Skip(3 * 2); // xAvgCharWidth, usWeightClass, usWidthClass
- $fsType = $this->ReadUShort();
- } else {
- $this->capHeight = 0;
- }
- }
- public function ParsePost(): void
- {
- $this->Seek('post');
- $version = $this->ReadULong();
- $this->italicAngle = $this->ReadShort();
- $this->Skip(2); // Skip decimal part
- } else {
- $this->glyphNames = false;
- }
- }
- public function Read($n)
- {
- return $n > 0 ? \fread($this->f, $n) : '';
- }
- public function ReadShort()
- public function Read($n)
- {
- return $n > 0 ? \fread($this->f, $n) : '';
- }
- public function ReadShort()
- {
- $a = \unpack('nn', \fread($this->f, 2));
- $v = $a['n'];
- if ($v >= 0x8000) {
- $v -= 65536;
- }
- return $v;
- }
- public function ReadULong()
- {
- $a = \unpack('NN', \fread($this->f, 4));
- return $a['N'];
- }
- $a = \unpack('NN', \fread($this->f, 4));
- return $a['N'];
- }
- public function ReadUShort()
- {
- $a = \unpack('nn', \fread($this->f, 2));
- return $a['n'];
- }
- $a = \unpack('nn', \fread($this->f, 2));
- return $a['n'];
- }
- public function Seek($tag): void
- {
- if (!isset($this->tables[$tag])) {
- $this->Error('Table not found: ' . $tag);
- }
- \fseek($this->f, $this->tables[$tag]['offset'], \SEEK_SET);
- $this->Error('Table not found: ' . $tag);
- }
- \fseek($this->f, $this->tables[$tag]['offset'], \SEEK_SET);
- }
- public function SetTable($tag, $data): void
- {
- $length = \strlen($data);
- $n = $length % 4;
- if ($n > 0) {
- $data = \str_pad($data, $length + 4 - $n, "\x00");
- $this->tables[$tag]['data'] = $data;
- $this->tables[$tag]['length'] = $length;
- $this->tables[$tag]['checkSum'] = $this->CheckSum($data);
- }
- public function Skip($n): void
- {
- \fseek($this->f, $n, \SEEK_CUR);
- }
- public function Subset($chars): void
- public function Skip($n): void
- {
- \fseek($this->f, $n, \SEEK_CUR);
- }
- public function Subset($chars): void
- {
- $this->subsettedGlyphs = [];
- $this->AddGlyph(0);
- $this->subsettedChars = [];
- foreach ($chars as $char) {
Your project should not use function in loops conditions
- Read doc
- Reputation
- Minor
More information: https://insight.symfony.com/what-we-analyse/php.for_loop_uses_test_function
- // Divide charset in contiguous segments
- $chars = $this->subsettedChars;
- \sort($chars);
- $segments = [];
- $segment = [$chars[0], $chars[0]];
- for ($i = 1; $i < \count($chars); ++$i) {
- if ($chars[$i] > $segment[1] + 1) {
- $segments[] = $segment;
- $segment = [$chars[$i], $chars[$i]];
- } else {
- ++$segment[1];