UnicodeWrite

Sample C# code for using Apryse SDK to create Unicode text and embed composite fonts in PDF files. Learn more about our Xamarin SDK.

1//
2// Copyright (c) 2001-2021 by PDFTron Systems Inc. All Rights Reserved.
3//
4
5using System;
6using System.IO;
7using System.Text;
8using pdftron;
9using pdftron.Common;
10using pdftron.Filters;
11using pdftron.SDF;
12using pdftron.PDF;
13
14using NUnit.Framework;
15
16namespace MiscellaneousSamples
17{
18 /// <summary>
19 /// This example illustrates how to create Unicode text and how to embed composite fonts.
20 /// </summary>
21 [TestFixture]
22 public class UnicodeWriteTest
23 {
24
25 // Note: This demo assumes that 'arialuni.ttf' is present in '/Samples/TestFiles'
26 // directory. Arial Unicode MS is about 24MB in size and it comes together with Windows and
27 // MS Office.
28 //
29 // For more information about Arial Unicode MS, please consult the following Microsoft Knowledge
30 // Base Article: WD2002: General Information About the Arial Unicode MS Font
31 // http://support.microsoft.com/support/kb/articles/q287/2/47.asp
32 //
33 // For more information consult:
34 // http://office.microsoft.com/search/results.aspx?Scope=DC&Query=font&CTT=6&Origin=EC010331121033
35 // http://www.microsoft.com/downloads/details.aspx?FamilyID=1F0303AE-F055-41DA-A086-A65F22CB5593
36 //
37 // In case you don't have access to Arial Unicode MS you can use cyberbit.ttf
38 // (ftp://ftp.netscape.com/pub/communicator/extras/fonts/windows/) instead.
39 //
40 [Test]
41 public static void Sample()
42 {
43
44 // Relative path to the folder containing test files.
45 const string input_path = "TestFiles/";
46
47 try
48 {
49 using (PDFDoc doc = new PDFDoc())
50 {
51 using (ElementBuilder eb = new ElementBuilder())
52 {
53 using (ElementWriter writer = new ElementWriter())
54 {
55 // Start a new page ------------------------------------
56 Page page = doc.PageCreate(new Rect(0, 0, 612, 794));
57
58 writer.Begin(page); // begin writing to this page
59
60 Font fnt = null;
61 try
62 {
63 // Full font embedding
64 fnt = Font.Create(doc, "Arial", "");
65 }
66 catch (PDFNetException e)
67 {
68 Console.WriteLine(e.Message);
69 Assert.True(false);
70 }
71
72 if (fnt == null) {
73 try
74 {
75 fnt = Font.CreateCIDTrueTypeFont(doc, Utils.GetAssetTempFile(input_path + "ARIALUNI.TTF"), true, true);
76 }
77 catch (PDFNetException e)
78 {
79 Console.WriteLine(e.Message);
80 Assert.True(false);
81 }
82 }
83
84 if (fnt == null)
85 {
86 try
87 {
88 fnt = Font.CreateCIDTrueTypeFont(doc, "C:/Windows/Fonts/ARIALUNI.TTF", true, true);
89 }
90 catch (PDFNetException e)
91 {
92 Console.WriteLine(e.Message);
93 Assert.True(false);
94 }
95 }
96
97 if (fnt == null)
98 {
99 Console.WriteLine("Note: using system font substitution for unshaped unicode text");
100 fnt = Font.Create(doc, "Helvetica", "");
101 }
102 else
103 {
104 Console.WriteLine("Note: using Arial Unicode for unshaped unicode text");
105 }
106
107 Element element = eb.CreateTextBegin(fnt, 1);
108 element.SetTextMatrix(10, 0, 0, 10, 50, 600);
109 element.GetGState().SetLeading(2); // Set the spacing between lines
110 writer.WriteElement(element);
111
112 // Hello World!!!
113 string hello = "Hello World!";
114 writer.WriteElement(eb.CreateUnicodeTextRun(hello));
115 writer.WriteElement(eb.CreateTextNewLine());
116
117 // Latin
118 char[] latin = {
119 'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', '\x45', '\x0046', '\x00C0',
120 '\x00C1', '\x00C2', '\x0143', '\x0144', '\x0145', '\x0152', '1', '2' // etc.
121 };
122 writer.WriteElement(eb.CreateUnicodeTextRun(new string(latin)));
123 writer.WriteElement(eb.CreateTextNewLine());
124
125 // Greek
126 char[] greek = {
127 (char)0x039E, (char)0x039F, (char)0x03A0, (char)0x03A1, (char)0x03A3,
128 (char)0x03A6, (char)0x03A8, (char)0x03A9 // etc.
129 };
130 writer.WriteElement(eb.CreateUnicodeTextRun(new string(greek)));
131 writer.WriteElement(eb.CreateTextNewLine());
132
133 // Cyrillic
134 char[] cyrillic = {
135 (char)0x0409, (char)0x040A, (char)0x040B, (char)0x040C, (char)0x040E, (char)0x040F, (char)0x0410, (char)0x0411,
136 (char)0x0412, (char)0x0413, (char)0x0414, (char)0x0415, (char)0x0416, (char)0x0417, (char)0x0418, (char)0x0419 // etc.
137 };
138 writer.WriteElement(eb.CreateUnicodeTextRun(new string(cyrillic)));
139 writer.WriteElement(eb.CreateTextNewLine());
140
141 // Hebrew
142 char[] hebrew = {
143 (char)0x05D0, (char)0x05D1, (char)0x05D3, (char)0x05D3, (char)0x05D4, (char)0x05D5, (char)0x05D6, (char)0x05D7, (char)0x05D8,
144 (char)0x05D9, (char)0x05DA, (char)0x05DB, (char)0x05DC, (char)0x05DD, (char)0x05DE, (char)0x05DF, (char)0x05E0, (char)0x05E1 // etc.
145 };
146 writer.WriteElement(eb.CreateUnicodeTextRun(new string(hebrew)));
147 writer.WriteElement(eb.CreateTextNewLine());
148
149 // Arabic
150 char[] arabic = {
151 (char)0x0624, (char)0x0625, (char)0x0626, (char)0x0627, (char)0x0628, (char)0x0629, (char)0x062A, (char)0x062B, (char)0x062C,
152 (char)0x062D, (char)0x062E, (char)0x062F, (char)0x0630, (char)0x0631, (char)0x0632, (char)0x0633, (char)0x0634, (char)0x0635 // etc.
153 };
154 writer.WriteElement(eb.CreateUnicodeTextRun(new string(arabic)));
155 writer.WriteElement(eb.CreateTextNewLine());
156
157 // Thai
158 char[] thai = {
159 (char)0x0E01, (char)0x0E02, (char)0x0E03, (char)0x0E04, (char)0x0E05, (char)0x0E06, (char)0x0E07, (char)0x0E08, (char)0x0E09,
160 (char)0x0E0A, (char)0x0E0B, (char)0x0E0C, (char)0x0E0D, (char)0x0E0E, (char)0x0E0F, (char)0x0E10, (char)0x0E11, (char)0x0E12 // etc.
161 };
162 writer.WriteElement(eb.CreateUnicodeTextRun(new string(thai)));
163 writer.WriteElement(eb.CreateTextNewLine());
164
165 // Hiragana - Japanese
166 char[] hiragana = {
167 (char)0x3041, (char)0x3042, (char)0x3043, (char)0x3044, (char)0x3045, (char)0x3046, (char)0x3047, (char)0x3048, (char)0x3049,
168 (char)0x304A, (char)0x304B, (char)0x304C, (char)0x304D, (char)0x304E, (char)0x304F, (char)0x3051, (char)0x3051, (char)0x3052 // etc.
169 };
170 writer.WriteElement(eb.CreateUnicodeTextRun(new string(hiragana)));
171 writer.WriteElement(eb.CreateTextNewLine());
172
173 // CJK Unified Ideographs
174 char[] cjk_uni = {
175 (char)0x5841, (char)0x5842, (char)0x5843, (char)0x5844, (char)0x5845, (char)0x5846, (char)0x5847, (char)0x5848, (char)0x5849,
176 (char)0x584A, (char)0x584B, (char)0x584C, (char)0x584D, (char)0x584E, (char)0x584F, (char)0x5850, (char)0x5851, (char)0x5852 // etc.
177 };
178 writer.WriteElement(eb.CreateUnicodeTextRun(new string(cjk_uni)));
179 writer.WriteElement(eb.CreateTextNewLine());
180
181 // Simplified Chinese
182 char[] chinese_simplified = {
183 (char)0x4e16, (char)0x754c, (char)0x60a8,(char) 0x597d
184 };
185 writer.WriteElement(eb.CreateUnicodeTextRun(new string(chinese_simplified)));
186 writer.WriteElement(eb.CreateTextNewLine());
187
188 // Finish the block of text
189 writer.WriteElement(eb.CreateTextEnd());
190 Console.WriteLine("Now using text shaping logic to place text");
191
192 // Create a font in indexed encoding mode
193 // normally this would mean that we are required to provide glyph indices
194 // directly to CreateUnicodeTextRun, but instead, we will use the GetShapedText
195 // method to take care of this detail for us.
196 Font indexedFont = Font.CreateCIDTrueTypeFont(doc, Utils.GetAssetTempFile(input_path + "NotoSans_with_hindi.ttf"), true, true, Font.Encoding.e_Indices);
197 element = eb.CreateTextBegin(indexedFont, 10.0);
198 writer.WriteElement(element);
199
200 double linePos = 350.0;
201 double lineSpace = 20.0;
202
203 // Transform unicode text into an abstract collection of glyph indices and positioning info
204 ShapedText shapedText = indexedFont.GetShapedText("Shaped Hindi Text:");
205
206 // transform the shaped text info into a PDF element and write it to the page
207 element = eb.CreateShapedTextRun(shapedText);
208 element.SetTextMatrix(1.5, 0, 0, 1.5, 50, linePos);
209 linePos -= lineSpace;
210 writer.WriteElement(element);
211
212 // read in unicode text lines from a file File. ReadAllLines(path, Encoding.UTF8)
213 String[] hindiTextLines = File.ReadAllLines(Utils.GetAssetTempFile(input_path + "hindi_sample_utf16le.txt"), Encoding.UTF8);
214
215 Console.WriteLine("Read in " + hindiTextLines.Length + " lines of Unicode text from file");
216 foreach (String textLine in hindiTextLines)
217 {
218 shapedText = indexedFont.GetShapedText(textLine);
219 element = eb.CreateShapedTextRun(shapedText);
220 element.SetTextMatrix(1.5, 0, 0, 1.5, 50, linePos);
221 linePos -= lineSpace;
222 writer.WriteElement(element);
223 Console.WriteLine("Wrote shaped line to page");
224 }
225
226 // Finish the shaped block of text
227 writer.WriteElement(eb.CreateTextEnd());
228
229 writer.End(); // save changes to the current page
230 doc.PagePushBack(page);
231 doc.Save(Utils.CreateExternalFile("unicodewrite.pdf"), SDFDoc.SaveOptions.e_remove_unused | SDFDoc.SaveOptions.e_hex_strings);
232 Console.WriteLine("Done. Result saved in unicodewrite.pdf...");
233 }
234 }
235 }
236 }
237 catch (PDFNetException e)
238 {
239 Console.WriteLine(e.Message);
240 Assert.True(false);
241 }
242 }
243 }
244}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales
Create Unicode Text, Embed CID Fonts in PDF in C# | Apryse documentation