Describe the bug
When generating a PDF with Arabic text, the library may throw the following exception:
Bad state: No element
Iterable.first
Tracing the issue shows it originates from:
Specifically this line:
glyphsInfo.add(glyphsMap[glyphsIndex] ?? glyphsMap.values.first);
If glyphsMap becomes empty, glyphsMap.values.first throws Bad state: No element, which provides no information about which character caused the failure.
After debugging and modifying the package locally, the failing character was:
This belongs to the Unicode block:
Arabic Presentation Forms-B (U+FE70–U+FEFF)
These characters often appear when text is copied from external sources (Word, PDFs, APIs, etc.) and many fonts do not contain glyphs for them.
The issue is therefore very difficult to diagnose because the thrown exception does not reveal the problematic character or text.
Suggested improvements
1️⃣ Better debugging / error reporting
Instead of throwing:
the library could provide a clearer error such as:
PdfFontException: Missing glyph for character 'ﻱ' (U+FEF1)
For example:
if (glyphsMap.isEmpty) {
throw PdfFontException(
"Missing glyph for character '${String.fromCharCode(char)}' "
"(U+${char.toRadixString(16).toUpperCase()})"
);
}
This would significantly improve debugging.
2️⃣ Optional normalization of compatibility characters
Many of these failures are caused by Unicode compatibility characters such as:
Arabic Presentation Forms
Ligatures
Compatibility glyphs
A potential solution would be to normalize input text using Unicode NFKC normalization, which converts these characters to their canonical forms.
Example using unorm_dart:
import 'package:unorm_dart/unorm_dart.dart' as unorm;
class TtfWriter {
Uint8List withChars(List<int> chars) {
...
for (final char in chars) {
var glyphsIndex = charMap[char];
if (glyphsIndex != null) {
var glyph = glyphsMap[glyphsIndex];
if (glyph == null) {
if (glyphsMap.isEmpty) {
final normalized = unorm.nfkc(String.fromCharCode(char));
if (normalized.isNotEmpty) {
final normalizedCode = normalized.runes.first;
final normalizedIndex = ttf.charToGlyphIndexMap[normalizedCode];
if (normalizedIndex != null &&
normalizedIndex < ttf.glyphOffsets.length) {
glyph = ttf.readGlyph(normalizedIndex).copy();
glyphsIndex = normalizedIndex;
}
}
}
if (glyph == null) {
final wholeText =
chars.map((e) => unorm.nfkc(String.fromCharCode(e))).join();
final codes = chars
.map((e) => 'U+${e.toRadixString(16).toUpperCase()}')
.join(', ');
print('⚠️ PDF glyph missing');
print('char: ${String.fromCharCode(char)}');
print('unicode: U+${char.toRadixString(16).toUpperCase()}');
print('text: $wholeText');
print('codes: $codes');
}
}
if (glyph != null) {
glyphsInfo.add(glyph);
glyphsMap.remove(glyphsIndex);
} else {
continue;
}
}
}
This would convert characters like:
and prevent missing glyph errors.
To Reproduce
Example that may trigger the issue when the font does not contain Arabic presentation glyphs:
final pdf = pw.Document();
pdf.addPage(
pw.Page(
build: (context) => pw.Text("ﻱ"),
),
);
await pdf.save();
This can produce:
Expected behavior
The library should either:
- Provide a clear error message identifying the missing glyph, or
- Optionally normalize compatibility characters before glyph lookup.
Flutter Doctor
Paste output of: flutter doctor -v
Desktop
Additional context
Arabic presentation forms frequently appear when text is copied from:
- Word documents
- PDFs
- ERP systems
- external APIs
Since the error message currently does not identify the problematic character, debugging this issue requires modifying the package source code.
Improved error reporting would make diagnosing font issues much easier.
Describe the bug
When generating a PDF with Arabic text, the library may throw the following exception:
Tracing the issue shows it originates from:
Specifically this line:
If
glyphsMapbecomes empty,glyphsMap.values.firstthrowsBad state: No element, which provides no information about which character caused the failure.After debugging and modifying the package locally, the failing character was:
This belongs to the Unicode block:
These characters often appear when text is copied from external sources (Word, PDFs, APIs, etc.) and many fonts do not contain glyphs for them.
The issue is therefore very difficult to diagnose because the thrown exception does not reveal the problematic character or text.
Suggested improvements
1️⃣ Better debugging / error reporting
Instead of throwing:
the library could provide a clearer error such as:
For example:
This would significantly improve debugging.
2️⃣ Optional normalization of compatibility characters
Many of these failures are caused by Unicode compatibility characters such as:
A potential solution would be to normalize input text using Unicode NFKC normalization, which converts these characters to their canonical forms.
Example using
unorm_dart:This would convert characters like:
and prevent missing glyph errors.
To Reproduce
Example that may trigger the issue when the font does not contain Arabic presentation glyphs:
This can produce:
Expected behavior
The library should either:
Flutter Doctor
Desktop
Additional context
Arabic presentation forms frequently appear when text is copied from:
Since the error message currently does not identify the problematic character, debugging this issue requires modifying the package source code.
Improved error reporting would make diagnosing font issues much easier.