diff --git a/app/Services/FontService.php b/app/Services/FontService.php index 13eef61c..1572fbdb 100644 --- a/app/Services/FontService.php +++ b/app/Services/FontService.php @@ -17,6 +17,35 @@ class FontService * Sans / Noto Sans CJK rebuilt as static TTF in Regular + Bold weights. */ public const FONT_PACKAGES = [ + 'noto-sans' => [ + 'name' => 'Noto Sans (Latin, Greek, Cyrillic)', + 'family' => 'NotoSans', + 'locales' => [], + 'size' => '~1.7MB', + 'bundled' => true, + 'files' => [ + [ + 'file' => 'NotoSans-Regular.ttf', + 'weight' => 'normal', + 'style' => 'normal', + ], + [ + 'file' => 'NotoSans-Bold.ttf', + 'weight' => 'bold', + 'style' => 'normal', + ], + [ + 'file' => 'NotoSans-Italic.ttf', + 'weight' => 'normal', + 'style' => 'italic', + ], + [ + 'file' => 'NotoSans-BoldItalic.ttf', + 'weight' => 'bold', + 'style' => 'italic', + ], + ], + ], 'noto-sans-sc' => [ 'name' => 'Noto Sans Simplified Chinese', 'family' => 'NotoSansCJKsc', @@ -97,6 +126,86 @@ class FontService ], ], ], + 'noto-sans-hebrew' => [ + 'name' => 'Noto Sans Hebrew', + 'family' => 'NotoSansHebrew', + 'locales' => ['he', 'yi'], + 'size' => '~40KB', + 'files' => [ + [ + 'file' => 'NotoSansHebrew-Regular.ttf', + 'url' => 'https://github.com/openmaptiles/fonts/raw/master/noto-sans/NotoSansHebrew-Regular.ttf', + 'weight' => 'normal', + 'style' => 'normal', + ], + [ + 'file' => 'NotoSansHebrew-Bold.ttf', + 'url' => 'https://github.com/openmaptiles/fonts/raw/master/noto-sans/NotoSansHebrew-Bold.ttf', + 'weight' => 'bold', + 'style' => 'normal', + ], + ], + ], + 'noto-naskh-arabic' => [ + 'name' => 'Noto Naskh Arabic (Arabic, Persian, Urdu)', + 'family' => 'NotoNaskhArabic', + 'locales' => ['ar', 'fa', 'ur', 'ckb'], + 'size' => '~285KB', + 'files' => [ + [ + 'file' => 'NotoNaskhArabic-Regular.ttf', + 'url' => 'https://github.com/openmaptiles/fonts/raw/master/noto-sans/NotoNaskhArabic-Regular.ttf', + 'weight' => 'normal', + 'style' => 'normal', + ], + [ + 'file' => 'NotoNaskhArabic-Bold.ttf', + 'url' => 'https://github.com/openmaptiles/fonts/raw/master/noto-sans/NotoNaskhArabic-Bold.ttf', + 'weight' => 'bold', + 'style' => 'normal', + ], + ], + ], + 'noto-sans-devanagari' => [ + 'name' => 'Noto Sans Devanagari (Hindi, Marathi, Sanskrit, Nepali)', + 'family' => 'NotoSansDevanagari', + 'locales' => ['hi', 'mr', 'sa', 'ne'], + 'size' => '~280KB', + 'files' => [ + [ + 'file' => 'NotoSansDevanagari-Regular.ttf', + 'url' => 'https://github.com/openmaptiles/fonts/raw/master/noto-sans/NotoSansDevanagari-Regular.ttf', + 'weight' => 'normal', + 'style' => 'normal', + ], + [ + 'file' => 'NotoSansDevanagari-Bold.ttf', + 'url' => 'https://github.com/openmaptiles/fonts/raw/master/noto-sans/NotoSansDevanagari-Bold.ttf', + 'weight' => 'bold', + 'style' => 'normal', + ], + ], + ], + 'sarabun' => [ + 'name' => 'Sarabun (Thai)', + 'family' => 'Sarabun', + 'locales' => ['th'], + 'size' => '~180KB', + 'files' => [ + [ + 'file' => 'Sarabun-Regular.ttf', + 'url' => 'https://github.com/google/fonts/raw/main/ofl/sarabun/Sarabun-Regular.ttf', + 'weight' => 'normal', + 'style' => 'normal', + ], + [ + 'file' => 'Sarabun-Bold.ttf', + 'url' => 'https://github.com/google/fonts/raw/main/ofl/sarabun/Sarabun-Bold.ttf', + 'weight' => 'bold', + 'style' => 'normal', + ], + ], + ], ]; /** @@ -126,13 +235,27 @@ class FontService } } + /** + * Resolve where a package's font files live on disk. + * Bundled packages ship with the repo under resources/static/fonts/; + * on-demand packages are downloaded into storage/fonts/. + */ + private function packageDir(array $package): string + { + return ! empty($package['bundled']) + ? resource_path('static/fonts') + : storage_path('fonts'); + } + /** * Check if a font package is installed (all files present). */ public function isInstalled(array $package): bool { + $dir = $this->packageDir($package); + foreach ($package['files'] as $entry) { - if (! File::exists(storage_path('fonts/'.$entry['file']))) { + if (! File::exists($dir.'/'.$entry['file'])) { return false; } } @@ -142,9 +265,14 @@ class FontService /** * Download a font package to storage/fonts/. + * No-op for bundled packages — those ship with the repo. */ public function downloadPackage(array $package): void { + if (! empty($package['bundled'])) { + return; + } + $fontsDir = storage_path('fonts'); if (! File::isDirectory($fontsDir)) { @@ -181,6 +309,7 @@ class FontService 'locales' => $package['locales'], 'size' => $package['size'], 'installed' => $this->isInstalled($package), + 'bundled' => ! empty($package['bundled']), ]; } @@ -195,15 +324,16 @@ class FontService public function getInstalledFontFaces(): array { $faces = []; - $fontsDir = storage_path('fonts'); foreach (self::FONT_PACKAGES as $package) { if (! $this->isInstalled($package)) { continue; } + $dir = $this->packageDir($package); + foreach ($package['files'] as $entry) { - $filePath = $fontsDir.'/'.$entry['file']; + $filePath = $dir.'/'.$entry['file']; $faces[] = "@font-face { font-family: '{$package['family']}'; diff --git a/lang/en.json b/lang/en.json index 6d8f273c..4c8af13f 100644 --- a/lang/en.json +++ b/lang/en.json @@ -1354,9 +1354,10 @@ }, "fonts": { "title": "Font Packages", - "description": "These font packages are used exclusively when generating PDF documents. The bundled Noto Sans already covers Latin, Cyrillic, Greek, Arabic, Thai and Hindi — install the packages below to render Chinese, Japanese or Korean characters in your PDFs.", - "bundled_info": "Noto Sans (bundled) covers Latin, Cyrillic, Greek, Arabic, Thai, Hindi, and most other scripts. Install additional packages below for CJK language support.", + "description": "These font packages are used exclusively when generating PDF documents. The bundled Noto Sans covers Latin, Greek and Cyrillic scripts. Install the packages below to render Hebrew, Arabic, Persian, Urdu, Hindi (Devanagari), Thai or East Asian (CJK) characters in your PDFs.", + "bundled_info": "Bundled font: Noto Sans (Latin / Greek / Cyrillic). Install additional packages below for Hebrew, Arabic, Persian, Hindi, Thai or CJK support.", "installed": "Installed", + "bundled": "Bundled", "install": "Install", "downloading": "Downloading...", "download_started": "Downloading {name}. This may take a moment.", diff --git a/resources/scripts-v2/features/admin/views/settings/AdminFontView.vue b/resources/scripts-v2/features/admin/views/settings/AdminFontView.vue index e0e6abef..e28c13a1 100644 --- a/resources/scripts-v2/features/admin/views/settings/AdminFontView.vue +++ b/resources/scripts-v2/features/admin/views/settings/AdminFontView.vue @@ -12,6 +12,7 @@ interface FontPackage { locales: string[] size: string installed: boolean + bundled?: boolean } const { t } = useI18n() @@ -84,7 +85,14 @@ async function installFont(pkg: FontPackage): Promise {
+ {{ $t('settings.fonts.bundled') }} + + + {{ $t('settings.fonts.installed') }} diff --git a/resources/static/fonts/THSarabunNew-Bold.ttf b/resources/static/fonts/THSarabunNew-Bold.ttf deleted file mode 100644 index a059996b..00000000 Binary files a/resources/static/fonts/THSarabunNew-Bold.ttf and /dev/null differ diff --git a/resources/static/fonts/THSarabunNew-BoldItalic.ttf b/resources/static/fonts/THSarabunNew-BoldItalic.ttf deleted file mode 100644 index e38f6d2f..00000000 Binary files a/resources/static/fonts/THSarabunNew-BoldItalic.ttf and /dev/null differ diff --git a/resources/static/fonts/THSarabunNew-Italic.ttf b/resources/static/fonts/THSarabunNew-Italic.ttf deleted file mode 100644 index 15312bc0..00000000 Binary files a/resources/static/fonts/THSarabunNew-Italic.ttf and /dev/null differ diff --git a/resources/static/fonts/THSarabunNew.ttf b/resources/static/fonts/THSarabunNew.ttf deleted file mode 100644 index 13c55aee..00000000 Binary files a/resources/static/fonts/THSarabunNew.ttf and /dev/null differ diff --git a/resources/views/app/pdf/locale/th.blade.php b/resources/views/app/pdf/locale/th.blade.php deleted file mode 100644 index 4c235682..00000000 --- a/resources/views/app/pdf/locale/th.blade.php +++ /dev/null @@ -1,34 +0,0 @@ - diff --git a/resources/views/app/pdf/partials/fonts.blade.php b/resources/views/app/pdf/partials/fonts.blade.php index 964e3532..7fd7d2b6 100644 --- a/resources/views/app/pdf/partials/fonts.blade.php +++ b/resources/views/app/pdf/partials/fonts.blade.php @@ -1,34 +1,7 @@ -{{-- Bundled Noto Sans — covers Latin, Cyrillic, Greek, Arabic, Thai, Hindi, and most scripts --}} +{{-- All @font-face rules — bundled and on-demand — are emitted by + FontService::getInstalledFontFaces(). Bundled packages live under + resources/static/fonts/, on-demand packages under storage/fonts/. --}}