/** * generate a font from a directory containing svg files (one file per glyph) * by naming convention the file name can specify which character should be mapped to the glyph * - my-icon.png => creates a glyph with the name 'my-icon' mapped to a character in the Unicode Private Use Area * - my-icon-x263a.png => creates a glyph with the name 'my-icon' mapped to the unicode character U+263A "☺" * * @param string $path SVG path definition (consider the font coordinate system has an inverted y axis) * @param array $fontOptions font options for the Font object * @param boolean $renameSourceFiles if true, files without mapping information will be renamed * @return static this */ public function generateFromDir($path, $fontOptions = array(), $renameSourceFiles = false) { $this->font = new Font($fontOptions); $this->mapping = array(); $fontOptions = $this->font->getOptions(); $files = scandir($path); foreach ($files as $fileName) { if (strtolower(substr($fileName, -4)) === '.svg') { if (preg_match('(^(.*)-x([0-9a-f]{2,6})\\.svg$)i', $fileName, $matches)) { $iconName = strtolower($matches[1]); $iconCode = static::hexToUnicode(strtolower($matches[2])); if (isset($this->mapping[$iconCode])) { throw new \Exception('Duplicate glyph ' . $iconCode . ' ' . $iconName); } $this->mapping[$iconCode] = array('path' => $path . DIRECTORY_SEPARATOR . $fileName, 'name' => $iconName); } } } foreach ($files as $fileName) { if (strtolower(substr($fileName, -4)) === '.svg') { if (!preg_match('(^(.*)-x([0-9a-f]{2,6})\\.svg$)i', $fileName)) { $iconName = strtolower(substr($fileName, 0, -4)); $code = hexdec('e001'); while (isset($this->mapping[static::hexToUnicode(dechex($code))])) { $code++; } if ($renameSourceFiles) { if (!rename($path . DIRECTORY_SEPARATOR . $fileName, $path . DIRECTORY_SEPARATOR . $iconName . '-x' . dechex($code) . '.svg')) { throw new \Exception('unable to rename "' . $path . DIRECTORY_SEPARATOR . $fileName . '"'); } $fileName = $iconName . '-x' . dechex($code) . '.svg'; } $this->mapping[static::hexToUnicode(dechex($code))] = array('path' => $path . DIRECTORY_SEPARATOR . $fileName, 'name' => $iconName); } } } foreach ($this->mapping as $code => $icon) { try { $iconDoc = new Document(file_get_contents($icon['path'])); $viewBox = $iconDoc->getViewBox(); $this->font->addGlyph($code, $iconDoc->getPath($fontOptions['units-per-em'] / $viewBox['height'], null, 'vertical', true, 0, $fontOptions['descent']), $icon['name'], round($viewBox['width'] * $fontOptions['units-per-em'] / $viewBox['height'])); } catch (\Exception $e) { throw new \Exception(basename($icon['path']) . ': ' . $e->getMessage()); } } return $this; }