diff options
Diffstat (limited to 'src/fonts.php')
| -rw-r--r-- | src/fonts.php | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/fonts.php b/src/fonts.php new file mode 100644 index 0000000..1959f51 --- /dev/null +++ b/src/fonts.php | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | <?php | ||
| 2 | // fonts.php — LIST server-side fonts via fontconfig | ||
| 3 | |||
| 4 | header('Content-Type: application/json'); | ||
| 5 | header('Cache-Control: public, max-age=3600'); | ||
| 6 | |||
| 7 | $output = shell_exec('fc-list --format="%{family}|%{file}\n" 2>/dev/null'); | ||
| 8 | if (!$output) { | ||
| 9 | echo json_encode([]); | ||
| 10 | exit; | ||
| 11 | } | ||
| 12 | |||
| 13 | $lines = array_filter(explode("\n", trim($output))); | ||
| 14 | $fonts = []; | ||
| 15 | $seen = []; | ||
| 16 | |||
| 17 | foreach ($lines as $line) { | ||
| 18 | $parts = explode('|', $line, 2); | ||
| 19 | if (count($parts) < 2) continue; | ||
| 20 | |||
| 21 | /* take first family name (some entries are comma-separated) */ | ||
| 22 | $families = explode(',', $parts[0]); | ||
| 23 | $family = trim($families[0]); | ||
| 24 | |||
| 25 | if (empty($family) || isset($seen[$family])) continue; | ||
| 26 | |||
| 27 | $file = trim($parts[1]); | ||
| 28 | if (!file_exists($file)) continue; | ||
| 29 | |||
| 30 | $seen[$family] = true; | ||
| 31 | |||
| 32 | $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); | ||
| 33 | $format = match ($ext) { | ||
| 34 | 'ttf' => 'truetype', | ||
| 35 | 'otf' => 'opentype', | ||
| 36 | 'woff' => 'woff', | ||
| 37 | 'woff2' => 'woff2', | ||
| 38 | default => 'truetype', | ||
| 39 | }; | ||
| 40 | |||
| 41 | $fonts[] = [ | ||
| 42 | 'family' => $family, | ||
| 43 | 'file' => base64_encode($file), | ||
| 44 | 'format' => $format, | ||
| 45 | ]; | ||
| 46 | } | ||
| 47 | |||
| 48 | usort($fonts, fn($a, $b) => strcasecmp($a['family'], $b['family'])); | ||
| 49 | echo json_encode($fonts); | ||
