php-gdlabel/src/FontRegistry.php

114 lines
3.1 KiB
PHP

<?php
namespace NoccyLabs\GdLabel;
class FontRegistry
{
private $fonts = [];
private static $instance = null;
public static function getInstance()
{
if (!self::$instance) {
self::$instance = new FontRegistry();
self::$instance->load();
}
return self::$instance;
}
public function load(string $lang='en')
{
exec("fc-list -v", $out, $ret);
$meta = []; $curr = [];
foreach ($out as $line) {
if (trim($line)) {
$curr[] = $line;
} else {
$meta[] = $curr;
$curr = [];
}
}
foreach ($meta as $font) {
$this->parseMeta($font, $lang);
}
}
private function parseMeta(array $meta, string $lang)
{
$coll = [];
foreach ($meta as $line) {
if (9 != ord($line[0]) or strpos($line,": ") === false or ctype_digit($line[1])) {
continue;
}
list ($key, $values) = explode(": ", substr($line, 1), 2);
if (preg_match('/.+lang$/', $key)) {
$base = substr($key, 0, -4);
$baseMeta = $coll[$base];
$vals = str_getcsv($baseMeta, ' ', '"');
$langs = str_getcsv($values, ' ', '"');
$keep = [];
while (count($langs)>0) {
$l = $this->parseValue(array_shift($langs));
$v = $this->parseValue(array_shift($vals));
if ($l == $lang) {
$keep[] = $v;
}
}
$coll[$base] = $keep;
} else {
$coll[$key] = $values;
}
}
foreach ($coll as $key=>$values) {
if (is_array($values)) {
continue;
}
$coll[$key] = $this->parseValue($values);
}
$langs = explode("|", $coll['lang']);
if (!in_array($lang, $langs)) {
return;
}
$this->fonts[] = (object)$coll;
}
private function parseValue($value)
{
if (substr($value, -3, 3) == "(s)") {
$value = substr($value, 0, -3);
if ($value && $value[0] == '"') {
$value = substr($value, 1, strpos($value, '"', 2)-1);
}
}
if (substr($value, -3, 3) == "(i)") {
$value = intval($value);
}
return $value;
}
public function findFont($family, $styles='regular')
{
$styles = explode(" ",$styles);
foreach ($this->fonts as $font) {
$families = array_map("strtolower", (array)$font->family);
if (!in_array(strtolower($family), $families)) {
continue;
}
$fontStyles = array_map("strtolower", $font->style);
foreach ($styles as $style) {
if (!in_array($style, $fontStyles)) {
continue(2);
}
}
if (count(array_diff($fontStyles, $styles))>0) {
continue;
}
return $font->file;
}
}
}