Bundle Noto Sans Arabic + Noto Sans JP (SIL OFL 1.1) as per-glyph fallbacks for both the UI text theme and every generated PDF, so RTL (Arabic) and CJK render on all platforms — including desktop, where the system font may lack them — instead of tofu. A shared pdf_fonts.dart centralizes the PDF theme and the three label/catalog/recovery services reuse it. Add Japanese (ja) as the CJK reference locale — fittingly, the app's own name is Japanese (種, tane, 'seed'). Core strings translated; the rest fall back to English via slang. Wired into supportedLocales (automatic) and the settings picker. Fix three physical Alignment.centerLeft -> AlignmentDirectional.centerStart in variety_detail_screen, and make month-abbreviation and avatar-initial truncation grapheme-safe (.characters) so CJK text is never cut mid-character. Tests: CJK/Arabic PDF glyph render, ja locale resolution + English fallback. The chat-bubble mirroring flagged by the audit was verified correct (already respects Directionality) and left unchanged.
38 lines
1.5 KiB
Dart
38 lines
1.5 KiB
Dart
import 'package:flutter/services.dart' show rootBundle;
|
|
import 'package:pdf/widgets.dart' as pw;
|
|
|
|
/// Fonts and theme shared by every generated PDF (labels, catalog, recovery
|
|
/// sheet). [theme] is the document-wide default; [bold] is exposed for the few
|
|
/// places that set a heading weight explicitly — merging against [theme] keeps
|
|
/// its script fallbacks, so bold Arabic/CJK still renders.
|
|
typedef PdfFonts = ({pw.ThemeData theme, pw.Font bold});
|
|
|
|
/// Loads the PDF fonts.
|
|
///
|
|
/// The base face is DejaVu (Latin extended, Cyrillic, Greek) with Noto Arabic
|
|
/// and Noto CJK registered as per-glyph fallbacks, so vernacular species names,
|
|
/// user notes, and localized labels in Arabic (RTL) or CJK render instead of
|
|
/// showing tofu boxes. The `pdf` package subsets fonts to the glyphs actually
|
|
/// used, so bundling the full Noto faces does not bloat the output file.
|
|
///
|
|
/// Fonts are a per-locale resource, extensible to any script — widen the
|
|
/// fallback list as more scripts land.
|
|
Future<PdfFonts> loadPdfFonts() async {
|
|
final base = pw.Font.ttf(
|
|
await rootBundle.load('assets/fonts/DejaVuSans.ttf'),
|
|
);
|
|
final bold = pw.Font.ttf(
|
|
await rootBundle.load('assets/fonts/DejaVuSans-Bold.ttf'),
|
|
);
|
|
final arabic = pw.Font.ttf(
|
|
await rootBundle.load('assets/fonts/NotoSansArabic.ttf'),
|
|
);
|
|
final cjk = pw.Font.ttf(await rootBundle.load('assets/fonts/NotoSansJP.ttf'));
|
|
final theme = pw.ThemeData.withFont(
|
|
base: base,
|
|
bold: bold,
|
|
italic: base,
|
|
fontFallback: [arabic, cjk],
|
|
);
|
|
return (theme: theme, bold: bold);
|
|
}
|