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