Question:
How do I add LTR/RTL (bidi) text to a PDF using C++?
Answer:
The easiest is to use our FlowDocument class which will handle this nicely for you. The below code adds the text
عندمانُشرالكتابفیعام 2019 قوبلبالتصفیق
Which according to google translates to
When the book was published in 2019, it was applauded.
The below C++ code accomplishes this (See the UnicodeWriteTest sample more examples of other languages).
FlowDocument flowdoc;
Paragraph para = flowdoc.AddParagraph();
TextStyledElement st_para = para.GetTextStyledElement();
st_para.SetFontSize(24);
st_para.SetTextColor(255, 0, 0);
Unicode arabic[]{
0x0639, 0x0646, 0x062F, 0x0645, 0x0627 , 0x0646, 0x064F, 0x0634, 0x0631 , 0x0627, 0x0644, 0x0643, 0x062A, 0x0627, 0x0628 , 0x0641, 0x064A , 0x0639, 0x0627, 0x0645 , 0x0032, 0x0030, 0x0031, 0x0039 , 0x0642, 0x0648, 0x0628, 0x0644 , 0x0628, 0x0627, 0x0644, 0x062A, 0x0635, 0x0641, 0x06CC, 0x0642
};
UString ustring(arabic, sizeof(arabic) / sizeof(Unicode));
para.AddText(ustring);
PDFDoc my_pdf = flowdoc.PaginateToPDF();
my_pdf.Save("created_doc.pdf", SDFDoc::e_linearized, 0);
If you wanted to use the lower level ElementBuilder API, then you would have to reverse the numbers “2019” to “9102” but then it will work as expected, see below.
PDFDoc doc;
ElementBuilder eb;
ElementWriter writer;
Page page = doc.PageCreate(Rect(0, 0, 612, 794));
writer.Begin(page); // begin writing to this page
// note, the bytes for the text "2019" is reversed below, because I need to reverse the arabic text
Unicode arabic[]{
0x0639, 0x0646, 0x062F, 0x0645, 0x0627 , 0x0646, 0x064F, 0x0634, 0x0631 , 0x0627, 0x0644, 0x0643, 0x062A, 0x0627, 0x0628 , 0x0641, 0x064A , 0x0639, 0x0627, 0x0645 , 0x0039, 0x0031, 0x0030, 0x0032 , 0x0642, 0x0648, 0x0628, 0x0644 , 0x0628, 0x0627, 0x0644, 0x062A, 0x0635, 0x0641, 0x06CC, 0x0642
};
int n = sizeof(arabic) / sizeof(arabic[0]);
std::reverse(arabic, arabic + n);
UString ustring(arabic, sizeof(arabic) / sizeof(Unicode));
Font fnt = Font::Create(doc, "arial", ustring);
Element element = eb.CreateTextBegin(fnt, 24);
element.SetTextMatrix(10, 0, 0, 10, 50, 600);
writer.WriteElement(eb.CreateUnicodeTextRun(arabic, sizeof(arabic)/sizeof(Unicode)));
writer.WriteElement(eb.CreateTextNewLine());
writer.WriteElement(eb.CreateTextEnd());
writer.End();
doc.PagePushBack(page);
doc.Save("unicodewrite.pdf", SDFDoc::e_remove_unused | SDFDoc::e_hex_strings, NULL);