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.
- Create a
Font
usingFont.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. - Create a
ShapedText
object usingfont.GetShapedText(yourText)
using the Font object from (1) above. - Use
ElementBuilder.CreateShapedTextRun
using theShapedText
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);
}