UnicodeWrite

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

1//---------------------------------------------------------------------------------------
2// Copyright (c) 2001-2019 by PDFTron Systems Inc. All Rights Reserved.
3// Consult legal.txt regarding legal and license information.
4//---------------------------------------------------------------------------------------
5
6package com.pdftron.android.pdfnetsdksamples.samples;
7
8import com.pdftron.android.pdfnetsdksamples.OutputListener;
9import com.pdftron.android.pdfnetsdksamples.PDFNetSample;
10import com.pdftron.android.pdfnetsdksamples.R;
11import com.pdftron.android.pdfnetsdksamples.util.Utils;
12import com.pdftron.pdf.Element;
13import com.pdftron.pdf.ElementBuilder;
14import com.pdftron.pdf.ElementWriter;
15import com.pdftron.pdf.Font;
16import com.pdftron.pdf.PDFDoc;
17import com.pdftron.pdf.Page;
18import com.pdftron.pdf.Rect;
19import com.pdftron.pdf.ShapedText;
20import com.pdftron.sdf.SDFDoc;
21
22import java.nio.charset.StandardCharsets;
23import java.nio.file.Files;
24import java.nio.file.Paths;
25import java.util.ArrayList;
26import java.util.List;
27
28/**
29 * This example illustrates how to create Unicode text and how to embed
30 * composite fonts.
31 * <p>
32 * Note: This sample assumes that your device contains some of the regular
33 * fonts distributed with the Android SDK. Since not all fonts are shipped
34 * depending on the manufacturer, you may need to change the sample code
35 * or add a font that covers the text you want to use.
36 * <p>
37 * In case some of the text used in this sample does not work properly
38 * (squared or dot characters appear instead of the real characters) you can
39 * search for the correct fonts in the Android SDK or download and use the
40 * Cyberbit font, available here:
41 * http://ftp.netscape.com/pub/communicator/extras/fonts/windows/
42 * <p>
43 * Add the font file to the assets\TestFiles folder and change the code
44 * accordingly.
45 */
46public class UnicodeWriteTest extends PDFNetSample {
47
48 private static OutputListener mOutputListener;
49
50 private static ArrayList<String> mFileList = new ArrayList<>();
51
52 public UnicodeWriteTest() {
53 setTitle(R.string.sample_unicodewrite_title);
54 setDescription(R.string.sample_unicodewrite_description);
55 }
56
57 @Override
58 public void run(OutputListener outputListener) {
59 super.run(outputListener);
60 mOutputListener = outputListener;
61 mFileList.clear();
62 printHeader(outputListener);
63
64 try (PDFDoc doc = new PDFDoc()) {
65 ElementBuilder eb = new ElementBuilder();
66 ElementWriter writer = new ElementWriter();
67
68 // Start a new page ------------------------------------
69 Page page = doc.pageCreate(new Rect(0, 0, 612, 794));
70
71 writer.begin(page); // begin writing to this page
72
73 String fontLocation = Utils.getAssetTempFile(INPUT_PATH + "ARIALUNI.TTF").getAbsolutePath();
74
75 Font fnt = null;
76 try {
77 // Embed and subset the font
78 fnt = Font.createCIDTrueTypeFont(doc, fontLocation, true, true);
79 } catch (Exception e) {
80 fontLocation = "C:/Windows/Fonts/ARIALUNI.TTF";
81 try {
82 fnt = Font.createCIDTrueTypeFont(doc, fontLocation, true, true);
83 }
84 catch (Exception e2) {
85 fontLocation = null;
86 }
87 }
88
89 if(fnt != null) {
90 mOutputListener.println("Note: using " + fontLocation + " for unshaped unicode text");
91 }
92 else {
93 mOutputListener.println("Note: using system font substitution for unshaped unicode text");
94 fnt = Font.create(doc, "Helvetica", "");
95 }
96
97 Element element = eb.createTextBegin(fnt, 1);
98 element.setTextMatrix(10, 0, 0, 10, 50, 600);
99 element.getGState().setLeading(2); // Set the spacing between lines
100 writer.writeElement(element);
101
102 // Hello World!
103 char hello[] = {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!'};
104 writer.writeElement(eb.createUnicodeTextRun(new String(hello)));
105 writer.writeElement(eb.createTextNewLine());
106
107 // Latin
108 char latin[] = {
109 'a', 'A', 'b', 'B', 'c', 'C', 'd', 'D', 0x45, 0x0046, 0x00C0,
110 0x00C1, 0x00C2, 0x0143, 0x0144, 0x0145, 0x0152, '1', '2' // etc.
111 };
112 writer.writeElement(eb.createUnicodeTextRun(new String(latin)));
113 writer.writeElement(eb.createTextNewLine());
114
115 // Greek
116 char greek[] = {
117 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A6, 0x03A8, 0x03A9 // etc.
118 };
119 writer.writeElement(eb.createUnicodeTextRun(new String(greek)));
120 writer.writeElement(eb.createTextNewLine());
121
122 // Cyrillic
123 char cyrilic[] = {
124 0x0409, 0x040A, 0x040B, 0x040C, 0x040E, 0x040F, 0x0410, 0x0411,
125 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419 // etc.
126 };
127 writer.writeElement(eb.createUnicodeTextRun(new String(cyrilic)));
128 writer.writeElement(eb.createTextNewLine());
129
130 // Hebrew
131 char hebrew[] = {
132 0x05D0, 0x05D1, 0x05D3, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, 0x05D8,
133 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, 0x05E0, 0x05E1 // etc.
134 };
135 writer.writeElement(eb.createUnicodeTextRun(new String(hebrew)));
136 writer.writeElement(eb.createTextNewLine());
137
138 // Arabic
139 char arabic[] = {
140 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062A, 0x062B, 0x062C,
141 0x062D, 0x062E, 0x062F, 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635 // etc.
142 };
143 writer.writeElement(eb.createUnicodeTextRun(new String(arabic)));
144 writer.writeElement(eb.createTextNewLine());
145
146 // Thai
147 char thai[] = {
148 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08, 0x0E09,
149 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, 0x0E10, 0x0E11, 0x0E12 // etc.
150 };
151 writer.writeElement(eb.createUnicodeTextRun(new String(thai)));
152 writer.writeElement(eb.createTextNewLine());
153
154 // Hiragana - Japanese
155 char hiragana[] = {
156 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049,
157 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3051, 0x3051, 0x3052 // etc.
158 };
159 writer.writeElement(eb.createUnicodeTextRun(new String(hiragana)));
160 writer.writeElement(eb.createTextNewLine());
161
162 // CJK Unified Ideographs
163 char cjk_uni[] = {
164 0x5841, 0x5842, 0x5843, 0x5844, 0x5845, 0x5846, 0x5847, 0x5848, 0x5849,
165 0x584A, 0x584B, 0x584C, 0x584D, 0x584E, 0x584F, 0x5850, 0x5851, 0x5852 // etc.
166 };
167 writer.writeElement(eb.createUnicodeTextRun(new String(cjk_uni)));
168 writer.writeElement(eb.createTextNewLine());
169
170 // Simplified Chinese
171 char chinese_simplified[] = {
172 0x4e16, 0x754c, 0x60a8, 0x597d
173 };
174 writer.writeElement(eb.createUnicodeTextRun(new String(chinese_simplified)));
175 writer.writeElement(eb.createTextNewLine());
176
177 // Finish the block of text
178 writer.writeElement(eb.createTextEnd());
179
180 mOutputListener.println("Now using text shaping logic to place text");
181
182 // Create a font in indexed encoding mode
183 // normally this would mean that we are required to provide glyph indices
184 // directly to CreateUnicodeTextRun, but instead, we will use the GetShapedText
185 // method to take care of this detail for us.
186 Font indexedFont = Font.createCIDTrueTypeFont(doc, Utils.getAssetTempFile(INPUT_PATH + "NotoSans_with_hindi.ttf").getAbsolutePath(), true, true, Font.e_Indices);
187 element = eb.createTextBegin(indexedFont, 10.0);
188 writer.writeElement(element);
189
190 double linePos = 350.0;
191 double lineSpace = 20.0;
192
193 // Transform unicode text into an abstract collection of glyph indices and positioning info
194 ShapedText shapedText = indexedFont.getShapedText("Shaped Hindi Text:");
195
196 // transform the shaped text info into a PDF element and write it to the page
197 element = eb.createShapedTextRun(shapedText);
198 element.setTextMatrix(1.5, 0, 0, 1.5, 50, linePos);
199 linePos -= lineSpace;
200 writer.writeElement(element);
201
202 // read in unicode text lines from a file
203 List<String> hindiTextLines = Files.readAllLines(Paths.get(Utils.getAssetTempFile(INPUT_PATH + "hindi_sample_utf16le.txt").getAbsolutePath()), StandardCharsets.UTF_16LE);
204
205 mOutputListener.println("Read in " + hindiTextLines.size() + " lines of Unicode text from file");
206 for (String textLine : hindiTextLines)
207 {
208 shapedText = indexedFont.getShapedText(textLine);
209 element = eb.createShapedTextRun(shapedText);
210 element.setTextMatrix(1.5, 0, 0, 1.5, 50, linePos);
211 linePos -= lineSpace;
212 writer.writeElement(element);
213 mOutputListener.println("Wrote shaped line to page");
214 }
215
216 // Finish the shaped block of text
217 writer.writeElement(eb.createTextEnd());
218
219 writer.end(); // save changes to the current page
220 doc.pagePushBack(page);
221
222 doc.save(Utils.createExternalFile("unicodewrite.pdf", mFileList).getAbsolutePath(), new SDFDoc.SaveMode[]{SDFDoc.SaveMode.REMOVE_UNUSED, SDFDoc.SaveMode.HEX_STRINGS}, null);
223 mOutputListener.println("Done. Result saved in unicodewrite.pdf...");
224 } catch (Exception e) {
225 mOutputListener.printError(e.getStackTrace());
226 }
227
228 for (String file : mFileList) {
229 addToFileList(file);
230 }
231 printFooter(outputListener);
232 }
233
234}

Did you find this helpful?

Trial setup questions?

Ask experts on Discord

Need other help?

Contact Support

Pricing or product questions?

Contact Sales