Implemented a proper font registry
This commit is contained in:
parent
c8abdce24a
commit
3fb9f18941
@ -7,52 +7,6 @@ use NoccyLabs\GdLabel\Element;
|
|||||||
class TextElement extends Element
|
class TextElement extends Element
|
||||||
{
|
{
|
||||||
|
|
||||||
private static $fontCache = [];
|
|
||||||
|
|
||||||
private static function findFont($font, $style='regular')
|
|
||||||
{
|
|
||||||
if (count(self::$fontCache)==0) {
|
|
||||||
self::updateFonts();
|
|
||||||
}
|
|
||||||
|
|
||||||
$font = strtolower($font);
|
|
||||||
|
|
||||||
if (array_key_exists($font, self::$fontCache)) {
|
|
||||||
$info = self::$fontCache[$font];
|
|
||||||
if (!$style) {
|
|
||||||
return $info;
|
|
||||||
}
|
|
||||||
if (array_key_exists($style, $info)) {
|
|
||||||
return $info[$style];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static function updateFonts()
|
|
||||||
{
|
|
||||||
exec("fc-list", $output, $ret);
|
|
||||||
if ($ret != 0) {
|
|
||||||
fprintf(STDERR, "%s\n", join("\n",$output));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
foreach ($output as $line) {
|
|
||||||
$seg = explode(":", $line);
|
|
||||||
$file = $seg[0];
|
|
||||||
$name = strtolower(trim(preg_replace("/[^A-Za-z0-9 ]/", '', $seg[1])));
|
|
||||||
$style = strtolower(str_replace("style=","",$seg[2]));
|
|
||||||
$style = explode(",",$style);
|
|
||||||
$style = reset($style);
|
|
||||||
|
|
||||||
if (!array_key_exists($name, self::$fontCache)) {
|
|
||||||
self::$fontCache[$name] = [];
|
|
||||||
}
|
|
||||||
self::$fontCache[$name][$style] = $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function draw($gd, int $x, int $y, int $width, int $height, array $params)
|
protected function draw($gd, int $x, int $y, int $width, int $height, array $params)
|
||||||
{
|
{
|
||||||
if (($bound = $this->getProp("bind-value"))) {
|
if (($bound = $this->getProp("bind-value"))) {
|
||||||
@ -62,8 +16,9 @@ class TextElement extends Element
|
|||||||
}
|
}
|
||||||
|
|
||||||
$fontName = $this->getProp("font")?:"liberation sans";
|
$fontName = $this->getProp("font")?:"liberation sans";
|
||||||
|
$fontStyle = $this->getProp("font-style")?:"regular";
|
||||||
|
$font = \NoccyLabs\GdLabel\FontRegistry::getInstance()->findFont($fontName, $fontStyle);
|
||||||
|
|
||||||
$font = self::findFont($fontName);
|
|
||||||
if (!$font) {
|
if (!$font) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
113
src/FontRegistry.php
Normal file
113
src/FontRegistry.php
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user