Ensure Arabic text displays correctly when printing documents

Update font configurations to exclusively use DIN Next LT Arabic, preload necessary font files, and implement eager font loading to prevent display issues during printing.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 77cfe984-2c65-4152-bb7a-0df28274fe66
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: 814df7a0-9300-4efe-a4b5-b5e474e8c99f
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/c3c252e4-c83d-40ca-9fff-99a3ea60701e/77cfe984-2c65-4152-bb7a-0df28274fe66/Ow4s0aa
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
riyadhafraa
2026-05-03 18:37:48 +00:00
parent a4e58b2263
commit 6cbd5968e5
5 changed files with 44 additions and 26 deletions
+7 -12
View File
@@ -12,23 +12,18 @@
is needed at page load, which speeds up first paint and removes
the external dependency.
#350 (browser print): preload the Arabic-shaping fonts used by
the print stylesheet (DIN Next LT Arabic — the app's default —
and Tajawal as the secondary). Without this, if the user has
never rendered text in these families on screen (e.g. their
preference is "Helvetica Neue" Latin), the browser would only
start downloading them when the print dialog opens. Print is a
synchronous snapshot and would capture the fallback glyphs —
isolated, unjoined Arabic letters that look reversed.
#350 (browser print): preload DIN Next LT Arabic — the app's
sole Arabic print font — so it's already in the HTTP cache by
the time `@font-face` (declared with `font-display: block` in
custom-fonts.css) wants to fetch it. Without this, Chrome's
print snapshot can be taken before the font is ready and the
output uses a system fallback that lacks Arabic GSUB shaping
(isolated, unjoined letters that look reversed).
-->
<link rel="preload" href="/fonts/DINNextLTArabic-Regular.ttf"
as="font" type="font/ttf" crossorigin="anonymous" />
<link rel="preload" href="/fonts/DINNextLTArabic-Bold.ttf"
as="font" type="font/ttf" crossorigin="anonymous" />
<link rel="preload" href="/fonts/Tajawal-Regular.ttf"
as="font" type="font/ttf" crossorigin="anonymous" />
<link rel="preload" href="/fonts/Tajawal-Bold.ttf"
as="font" type="font/ttf" crossorigin="anonymous" />
</head>
<body>
<div id="root"></div>
+13 -6
View File
@@ -11,41 +11,48 @@
* setFontFamily(value) will not match these declarations.
*/
/* ── DIN Next LT Arabic ─────────────────────────────────────────── */
/* ── DIN Next LT Arabic ───────────────────────────────────────────
* #350 (browser print): font-display set to `block` (not `swap`) so
* Chrome will WAIT for the font to be ready instead of rasterizing
* the print snapshot with a fallback that lacks Arabic GSUB shaping.
* This is the app's primary Arabic font — block-period delays first
* paint by at most ~3s but the file is already in cache from the
* <link rel="preload"> in index.html, so the practical wait is 0ms.
*/
@font-face {
font-family: "DIN Next LT Arabic";
src: url("/fonts/DINNextLTArabic-UltraLight.ttf") format("truetype");
font-weight: 200;
font-style: normal;
font-display: swap;
font-display: block;
}
@font-face {
font-family: "DIN Next LT Arabic";
src: url("/fonts/DINNextLTArabic-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
font-display: swap;
font-display: block;
}
@font-face {
font-family: "DIN Next LT Arabic";
src: url("/fonts/DINNextLTArabic-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
font-display: swap;
font-display: block;
}
@font-face {
font-family: "DIN Next LT Arabic";
src: url("/fonts/DINNextLTArabic-Bold.ttf") format("truetype");
font-weight: 700;
font-style: normal;
font-display: swap;
font-display: block;
}
@font-face {
font-family: "DIN Next LT Arabic";
src: url("/fonts/DINNextLTArabic-Black.ttf") format("truetype");
font-weight: 900;
font-style: normal;
font-display: swap;
font-display: block;
}
/* ── Tajawal ────────────────────────────────────────────────────── */
+10 -8
View File
@@ -366,17 +366,19 @@
* bidi algorithm on those isolated glyphs, the text appears reversed
* (e.g. "قائمة" prints as "ةمئاق").
*
* Fix: in print mode, force the printable schedule region onto a
* web font that we ship with the app and that has full Arabic
* shaping (Tajawal). Also explicitly enable common-ligatures and
* contextual-alternates (`liga`, `calt`) which drive Arabic joining,
* and pin direction to RTL when the page is in Arabic so Chrome
* doesn't mis-resolve bidi for cells whose first glyph is Latin.
* Fix: in print mode, force every element onto DIN Next LT Arabic
* (the app's primary Arabic font, which has a full GSUB shaping
* table). Combined with `font-display: block` in custom-fonts.css
* and `<link rel="preload">` in index.html, this ensures Chrome
* never falls back to a system font during the print snapshot. We
* also explicitly enable common-ligatures and contextual-alternates
* (`liga`, `calt`) which drive Arabic joining, and pin direction to
* RTL when the page is in Arabic so Chrome doesn't mis-resolve bidi
* for cells whose first glyph is Latin.
*/
@media print {
html, body, body * {
font-family: "DIN Next LT Arabic", "Tajawal",
"Helvetica Neue LT Arabic", "Segoe UI", Tahoma, Arial, sans-serif !important;
font-family: "DIN Next LT Arabic", sans-serif !important;
font-feature-settings: "liga" 1, "calt" 1, "rlig" 1 !important;
-webkit-font-feature-settings: "liga" 1, "calt" 1, "rlig" 1 !important;
text-rendering: optimizeLegibility;
+14
View File
@@ -3,4 +3,18 @@ import "./i18n";
import App from "./App";
import "./index.css";
// #350 (browser print): eagerly trigger DIN Next LT Arabic downloads
// via the CSS Font Loading API. The <link rel="preload"> in
// index.html only warms the HTTP cache; it does not register the font
// with the browser's font system. Calling `document.fonts.load()`
// here resolves the @font-face declaration immediately so the font is
// fully ready before the user opens the print dialog (Ctrl+P) — even
// if no on-screen element happens to render in DIN Next yet. Without
// this, Chrome's print snapshot can fall back to a system font that
// lacks Arabic GSUB shaping, producing isolated/reversed letters.
if (typeof document !== "undefined" && document.fonts?.load) {
void document.fonts.load('400 1em "DIN Next LT Arabic"');
void document.fonts.load('700 1em "DIN Next LT Arabic"');
}
createRoot(document.getElementById("root")!).render(<App />);