You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When generating a PDF invoice using the pdf package, the Khmer script's "Khmer Sign Coeng" (្) is not rendering correctly with Khmer letters. This diacritical mark, essential for forming certain consonant clusters, fails to combine properly with the preceding and following Khmer characters, resulting in incorrect and unreadable text.
Example
Correct Rendering: បន្ទាត់ (a valid Khmer word)
Incorrect Rendering:
(shows the issue with "Khmer Sign Coeng" not combining correctly)
To Reproduce
Code snippet to reproduce the behavior:
Future<String> generatePdfInvoice(PdfPageFormat format, List<Invoice> invoiceItems) async {
final pdf = pw.Document();
final img =await rootBundle.load('assets/images/header_invoice.png');
final imageBytes = img.buffer.asUint8List();
// final khmerFont = pw.Font.ttf(await rootBundle.load('assets/fonts/Khmer-OS-Siemreap-Regular.ttf'));finalUint8List fontData =base64Decode(khmerFontBase64);
final khmerFont = pw.Font.ttf(fontData.buffer.asByteData());
// Define the maximum number of items per pageconstint itemsPerPage =33;
// Split the invoice items into chunks of itemsPerPageList<List<Invoice>> chunks = [];
for (var i =0; i < invoiceItems.length; i += itemsPerPage) {
chunks.add(invoiceItems.sublist(
i,
i + itemsPerPage > invoiceItems.length ? invoiceItems.length : i + itemsPerPage,
));
}
// Add a page for each chunk of invoice itemsfor (var i =0; i < chunks.length; i++) {
final chunk = chunks[i];
pdf.addPage(
pw.MultiPage(
theme: pw.ThemeData.withFont(
base: khmerFont,
),
pageFormat:PdfPageFormat.a4,
build: (pw.Context context) {
return<pw.Widget>[
if (i ==0)
pw.Container(
alignment: pw.Alignment.center,
child: pw.Image(pw.MemoryImage(imageBytes)),
),
if (i ==0)
pw.Container(
child: pw.Divider(
height:1,
thickness:1,
indent:1,
endIndent:0,
color:PdfColor.fromHex("#000000"),
),
),
pw.SizedBox(height:20),
if (i ==0)
pw.Row(
children: [
pw.Container(
child: pw.Row(
children: [
pw.Column(
crossAxisAlignment: pw.CrossAxisAlignment.start,
children: [
pw.Text("Billed To", style: pw.TextStyle(color:PdfColor.fromHex("#5453C6"))),
pw.Text("Client Name : ${nameController.text.toString()}"),
pw.Text("Address : ${addressController.text.toString()}"),
pw.Text("Tel: ${telController.text.toString()}"),
]
),
pw.SizedBox(width:80), // Add horizontal space between text elements
pw.Column(
mainAxisAlignment: pw.MainAxisAlignment.center,
children: [
pw.Text("Date Issued", style: pw.TextStyle(color:PdfColor.fromHex("#5453C6"))),
pw.Text("${dateController.text.toString()}"),
]
),
pw.SizedBox(width:15),
pw.Column(
mainAxisAlignment: pw.MainAxisAlignment.center,
children: [
pw.Text("Invoice Number", style: pw.TextStyle(color:PdfColor.fromHex("#5453C6"))),
pw.Text("${numController.text.toString()}"),
]
),
],
),
),
],
),
pw.SizedBox(height:20),
// Table construction using pw.Table.fromTextArray
pw.Table.fromTextArray(
border:null,
cellAlignment: pw.Alignment.center,
headerDecoration: pw.BoxDecoration(color:PdfColors.grey300),
headerHeight:30,
cellHeight:30,
headerStyle: pw.TextStyle(fontWeight: pw.FontWeight.bold, font: khmerFont),
headers: ['No', 'Description', 'Qty', 'Unit Price', 'Amount'],
data:List<List<dynamic>>.generate(
chunk.length,
(index) => [
'${index + 1}',
chunk[index].description,
chunk[index].qty,
pw.Text(
'${chunk[index].price} ${chunk[index].cur == "R" ? "\R" : "\$"}',
style: pw.TextStyle(fontSize:12),
),
'${chunk[index].qty * chunk[index].price} ${chunk[index].cur == "R" ? "\R" : "\$"}',
],
),
),
pw.SizedBox(height:20),
if (i == chunks.length -1)
pw.Row(
mainAxisAlignment: pw.MainAxisAlignment.end,
children: [
pw.Column(
mainAxisAlignment: pw.MainAxisAlignment.end,
children: [
pw.Text('Total Amount Riel: ${totalRController.text} R',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Text('Total Amount USD : ${totalUController.text} \$',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Text('Total Due Amount Riel : ${totalDueRController.text} R',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
pw.Text('Total Due Amount USD : ${totalDueUController.text} \$',
style: pw.TextStyle(fontWeight: pw.FontWeight.bold)),
],
)
]
)
];
},
),
);
}
final output =awaitgetTemporaryDirectory();
final invoice_num = numController.text;
final file =File("${output.path}/${invoice_num.toString()}.pdf");
await file.writeAsBytes(await pdf.save());
return file.path;
}
Expected behavior
The "Khmer Sign Coeng" (្) should combine seamlessly with preceding and following Khmer letters to form valid consonant clusters, ensuring that the text is rendered correctly and is readable.
Screenshots
Flutter Doctor
Desktop (please complete the following information):
iOS
Android
Browser
Windows
Linux
Smartphone (please complete the following information):
Device: [e.g. iPhone6]
OS: [e.g. iOS8.1]
Browser [e.g. stock browser, safari]
Version [e.g. 22]
Additional context
The text was updated successfully, but these errors were encountered:
Describe the bug
When generating a PDF invoice using the pdf package, the Khmer script's "Khmer Sign Coeng" (្) is not rendering correctly with Khmer letters. This diacritical mark, essential for forming certain consonant clusters, fails to combine properly with the preceding and following Khmer characters, resulting in incorrect and unreadable text.
Example
Correct Rendering: បន្ទាត់ (a valid Khmer word)
Incorrect Rendering:
(shows the issue with "Khmer Sign Coeng" not combining correctly)
To Reproduce
Code snippet to reproduce the behavior:
Expected behavior
The "Khmer Sign Coeng" (្) should combine seamlessly with preceding and following Khmer letters to form valid consonant clusters, ensuring that the text is rendered correctly and is readable.
Screenshots
Flutter Doctor
Desktop (please complete the following information):
Smartphone (please complete the following information):
Additional context
The text was updated successfully, but these errors were encountered: