How to write Diacritic text such as Khmer (Cambodian)?

Question:
How do I write out Diacritic languages, like Khmer?

Answer
You can use the shaping engine, which will handle kerning, ligatures, and diacritic positioning for you. To do this you need to satisfy the following.

  1. Create a Font using Font.CreateCIDTrueTypeFont(PDFDoc, pathToFontFile, true, true, Font.Encoding.e_Indices) to create a CID Type0 font which will write glyph indices, rather than unicode, to the PDF page content stream.
  2. Create a ShapedText object using font.GetShapedText(yourText) using the Font object from (1) above.
  3. Use ElementBuilder.CreateShapedTextRun using the ShapedText object you got from (2) above.

Font::CreateCIDTrueTypeFont
Font::GetShapedText
ElementBuilder::CreateShapedTextRun

Below is example C# code, modified ElementBuilder sample. Other language bindings would be essentially identical to this. Replace the Font with one that has coverage for the text you want to display.

try
{
	using (PDFDoc pdfdoc = new PDFDoc())
	using (ElementBuilder elementBuilder = new ElementBuilder())
	using (ElementWriter elementWriter = new ElementWriter())
	{
		Page page = pdfdoc.PageCreate(new Rect(0, 0, 612, 794));

		elementWriter.Begin(page);
		string text = "សួស្តី​ពិភពលោក";

		// we need to select Indices encoding for shaping
		pdftron.PDF.Font font = pdftron.PDF.Font.CreateCIDTrueTypeFont(pdfdoc, @"c:\Windows\Fonts\LeelawUI.ttf", true, true, Font.Encoding.e_Indices);

		var element = elementBuilder.CreateTextBegin(font, 32);
		elementWriter.WriteElement(element);

		ShapedText shapedText = font.GetShapedText(text);
		ShapedText.FailureReason failureReason = shapedText.GetFailureReason();
		if (failureReason != ShapedText.FailureReason.e_no_failure)
		{
			throw new Exception(failureReason.ToString());
		}
		ShapedText.ShapingStatus shapingStatus = shapedText.GetShapingStatus();
		Console.WriteLine(shapingStatus);

		element = elementBuilder.CreateShapedTextRun(shapedText);
		element.SetTextMatrix(1, 0, 0, 1, 72, 600);
		elementWriter.WriteElement(element);

		elementWriter.WriteElement(elementBuilder.CreateTextEnd());

		elementWriter.End();
		pdfdoc.PagePushBack(page);

		pdfdoc.Save(pathToSavePdfFile, SDFDoc.SaveOptions.e_remove_unused);
	}
}
catch (Exception e)
{
	Console.WriteLine(e);
}