KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > CharacterMap


1 import java.util.*;
2 import java.io.*;
3 import java.awt.Color JavaDoc;
4 import org.faceless.pdf2.*;
5
6 /**
7  * A more complex example which creates a Unicode Character Map, showing
8  * every character in the font. Not terribly efficient, but good as a
9  * demonstration, and actually useful as well.
10  */

11 public class CharacterMap
12 {
13     // This method actually does the grunt work of creating the PDF page.
14
// If you're reading this source to find out about creating PDF's, this
15
// routine is the main, if not the only one you need to look at.
16
// Consequently we've put it at the top of the class so you can't miss
17
// it, at the expense of clarity of the overall source.
18
//
19
// start - the first character on the page
20
// end - the last character on the page. No more than 128 after the start.
21
// name - the name of the page (for the title).
22
//
23
private static PDFPage addPage(PDF p, char start, char end, String JavaDoc name, PDFFont f)
24     {
25     final int mod=16; // Number of characters per column.
26

27     // Create the page
28
//
29
PDFPage page = p.newPage(PDF.PAGESIZE_A4);
30
31     // Create some styles. For efficiency these should be created
32
// once, elsewhere, and passed in. For clarity, they aren't.
33
//
34
// "fontstyle" is used to actually render the glyphs.
35
//
36
PDFStyle fontstyle = new PDFStyle();
37     fontstyle.setFillColor(Color.black);
38     fontstyle.setFont(f,12);
39     fontstyle.setTextAlign(PDFStyle.TEXTALIGN_CENTER);
40
41     // "titlestyle". Guess what this is for.
42
//
43
PDFStyle titlestyle = new PDFStyle();
44     titlestyle.setFont(new StandardFont(StandardFont.HELVETICA), 18);
45     titlestyle.setFillColor(Color.black);
46     titlestyle.setTextAlign(PDFStyle.TEXTALIGN_CENTER);
47
48     // "numberstyle" is for the "U+xxxx" notes in each character box
49
//
50
PDFStyle numberstyle = new PDFStyle();
51     numberstyle.setFont(new StandardFont(StandardFont.HELVETICAOBLIQUE), 6);
52     numberstyle.setFillColor(Color.black);
53     numberstyle.setTextAlign(PDFStyle.TEXTALIGN_RIGHT);
54
55     // "hollowboxstyle" is to surround glyphs that actually exist
56
//
57
PDFStyle hollowboxstyle = new PDFStyle();
58     hollowboxstyle.setLineColor(Color.black);
59
60     // "greyboxstyle" is to surround glyphs that don't exist.
61
//
62
PDFStyle greyboxstyle = (PDFStyle)hollowboxstyle.clone();
63     greyboxstyle.setFillColor(Color.gray);
64
65
66     // Create the page content.
67

68
69
70     // Add the title, centered on the page 50 points from the top.
71
//
72
page.setStyle(titlestyle);
73     page.drawText(name+" ("+toHex(start)+" - "+toHex(end)+")", page.getWidth()/2, page.getHeight()-50);
74
75     // Crucially, the page is measured in PERCENT. This makes laying out grids
76
// much easier.
77
//
78

79     page.setUnits(PDFPage.UNITS_PERCENT , PDFPage.ORIGIN_PAGETOP);
80
81     float h = (95/mod); // height of each box, in percent
82
float w = (95/8); // width of each box, in percent
83

84     int left = 10; // Position to start drawing table in percent
85
int top = 10; //
86

87
88     for (char c=start; c<end; c++)
89     {
90         // Calculate row and column for this glyph.
91
//
92
int row=(( c - start) % mod);
93         int col=(int)Math.floor(( c - start) / mod);
94
95         // If the character is defined, draw a hollow box, then
96
// place the glyph in the center.
97
//
98
// If it's not defined, draw a gray box
99
//
100
if (f.isDefined(c)) {
101         page.setStyle(hollowboxstyle);
102         page.drawRectangle(left+(col*w),top+(row*h),left + ((col+1)*w),top + ((row+1)*h));
103         page.setStyle(fontstyle);
104         page.drawText(""+c, left+((col+0.5f)*w), top+((row+0.6f)*h));
105         } else {
106         page.setStyle(greyboxstyle);
107         page.drawRectangle( left+(col*w), top+(row*h),left + ((col+1)*w),top +((row+1)*h));
108         }
109
110         // Add the Unicode number to the box at the bottom right
111
//
112
page.setStyle(numberstyle);
113         page.drawText(toHex(c), left+((col+0.9f)*w), top+((row+0.9f)*h));
114     }
115     return page;
116     }
117
118
119
120     //-----------------------------------------------------------------------
121
// Rest of the program continues from here on.
122

123
124
125     // The start of the Unicode code blocks. Lifted gratefully from
126
// the source to java.lang.Character.UnicodeBlock.
127
//
128
private static final char[] blocks = { '\u0000', '\u0080', '\u0100', '\u0180', '\u0250', '\u02B0', '\u0300', '\u0370', '\u0400', '\u0500', '\u0530', '\u0590', '\u0600', '\u0700', '\u0900', '\u0980', '\u0A00', '\u0A80', '\u0B00', '\u0B80', '\u0C00', '\u0C80', '\u0D00', '\u0D80', '\u0E00', '\u0E80', '\u0F00', '\u0FC0', '\u10A0', '\u1100', '\u1200', '\u1E00', '\u1F00', '\u2000', '\u2070', '\u20A0', '\u20D0', '\u2100', '\u2150', '\u2190', '\u2200', '\u2300', '\u2400', '\u2440', '\u2460', '\u2500', '\u2580', '\u25A0', '\u2600', '\u2700', '\u27C0', '\u3000', '\u3040', '\u30A0', '\u3100', '\u3130', '\u3190', '\u3200', '\u3300', '\u3400', '\u4E00', '\uA000', '\uAC00', '\uD7A4', '\uD800', '\uE000', '\uF900', '\uFB00', '\uFB50', '\uFE00', '\uFE20', '\uFE30', '\uFE50', '\uFE70', '\uFF00' };
129
130
131     public static void main(String JavaDoc[] args)
132         throws IOException
133     {
134     // First load the font from the command line arguments.
135
//
136
PDFFont f = null;
137     try {
138         f = selectFont(args);
139     } catch (IOException e) {
140         e.printStackTrace();
141         System.exit(1);
142     }
143
144     // Create a new PDF
145
//
146
PDF p = new PDF();
147     // p.setOutputProfile(OutputProfile.NoCompression); // For debugging
148

149     List bookmarks = p.getBookmarks();
150
151     // Add some pages for each block to the document. There may
152
// not be any characters defined for this block, in which case
153
// addBlock() adds no pages and returns null.
154
//
155
for (int i=0;i<blocks.length-1;i++)
156     {
157         Character.UnicodeBlock JavaDoc b = Character.UnicodeBlock.of(blocks[i]);
158         if (b!=null && !b.toString().equals("CJK_UNIFIED_IDEOGRAPHS") && !b.toString().equals("HANGUL_SYLLABLES")) {
159         String JavaDoc blockname = b.toString();
160         PDFPage first = addBlock(p, blocks[i], blocks[i+1], blockname, f);
161         if (first!=null) {
162             bookmarks.add(new PDFBookmark(blockname, PDFAction.goTo(first)));
163         }
164         }
165     }
166
167     // Set some meta-information. Google is indexing PDF's these
168
// days, so this is more useful than you might think.
169
//
170
p.setInfo("Author", "Big Faceless Organization, Inc.");
171     p.setInfo("Title", "Character map for \""+f.getBaseName()+"\"");
172     p.setInfo("Subject", "Shows the Unicode codepoints for the \""+f.getBaseName()+"\" font.");
173     p.setInfo("Keywords", f.getBaseName()+", Unicode, character map, font");
174
175     // Write the document to a file
176
//
177
OutputStream fo = new FileOutputStream("CharacterMap.pdf");
178     p.render(fo);
179     fo.close();
180     }
181
182
183     //---------------------------------------------------------------------
184

185
186     // Add some pages (if necessary) to the document for this Unicode Block.
187
// If no characters are defined in this range, add nothing and return null,
188
// otherwise return the first page created (for bookmarking)
189
//
190
// start - the first character in the blocks range
191
// end - the last character in the blocks range
192
// name - the name of the block (to be added as a title on each page)
193
//
194
private static PDFPage addBlock(PDF p, char start, char end, String JavaDoc name, PDFFont f)
195     {
196     PDFPage firstpage=null;
197     boolean entries_in_this_block = false;
198
199     // Establish if there are any entries in this range
200
//
201
if (Character.UnicodeBlock.of(start)!=null) {
202         for (char c=start; c<end; c++) {
203            if (f.isDefined(c)) {
204            entries_in_this_block = true;
205            }
206         }
207     }
208
209     // There are. Add one (or more) pages of 128 glyphs each.
210
//
211
if (entries_in_this_block)
212     {
213         System.out.println("Rendering "+name);
214         for (char pagestart=start; pagestart<end; pagestart+=128)
215         {
216         // Next, establish if there are characters on this page.
217
// More efficient souls than myself would check this in
218
// the loop above and store the results.
219
//
220
boolean entries_in_this_page = false;
221         char pageend = (char)(pagestart+128);
222         if (pageend>end) {
223             pageend = end;
224         }
225         for (char c=pagestart; c<pageend; c++) {
226             if (f.isDefined(c)) {
227                 entries_in_this_page=true;
228             }
229         }
230
231         // Yes, there are entries on this page. Create it
232
//
233
if (entries_in_this_page) {
234             System.out.println("* "+toHex(pagestart)+" to "+toHex(pageend));
235             PDFPage page = addPage(p, pagestart, pageend, name, f);
236             if (firstpage==null) {
237             firstpage=page;
238             }
239         }
240         }
241     }
242     return firstpage;
243     }
244
245
246     // This unpleasant piece of code loads and returns the font
247
// specified on the command line.
248
//
249
private static PDFFont selectFont(String JavaDoc[] args)
250         throws IOException
251     {
252     PDFFont font = null;
253
254     String JavaDoc ttfname=null, afmname=null, pfbname=null, stdname=null;
255     String JavaDoc[] names = { "Times-Roman",
256                 "Times-Bold",
257                 "Times-Italic",
258                 "Times-BoldItalic",
259                 "Helvetica",
260                 "Helvetica-Bold",
261                 "Helvetica-Oblique",
262                 "Helvetica-BoldOblique",
263                 "Courier",
264                 "Courier-Bold",
265                 "Courier-Oblique",
266                 "Courier-BoldOblique",
267                 "Symbol",
268                 "ZapfDingbats"
269             };
270
271         int numbytes = 2;
272     for (int i=0;i<args.length;i+=2) {
273         if (args[i].equals("--ttf")) {
274             ttfname = args[i+1];
275         } else if (args[i].equals("--ttf1")) {
276             ttfname = args[i+1];
277                 numbytes = 1;
278         } else if (args[i].equals("--ttf2")) {
279             ttfname = args[i+1];
280         } else if (args[i].equals("--afm")) {
281             afmname = args[i+1];
282         } else if (args[i].equals("--pfb")) {
283             pfbname = args[i+1];
284         } else if (args[i].equals("--builtin")) {
285             stdname = args[i+1];
286         }
287     }
288
289     if (stdname!=null) {
290         for (int i=0;i<names.length;i++) {
291             if (names[i].equals(stdname)) {
292             font = new StandardFont(i);
293         }
294         }
295         if (font==null) {
296         throw new Error JavaDoc("No Such Standard Font: \""+stdname+"\"");
297         }
298     } else if (ttfname!=null) { // Assume TTF is to be embedded
299
font = new OpenTypeFont(new FileInputStream(ttfname), numbytes);
300     } else if (afmname!=null) {
301         font = new Type1Font(new FileInputStream(afmname), (pfbname==null ? null : new FileInputStream(pfbname)));
302     } else {
303         System.out.println("Usage: java CharacterMap [ --ttf <truetype font file> ] |");
304         System.out.println(" [ --afm <AFM file> [ --pfb <PFB file> ]] |");
305         System.out.println(" [ --builtin < Courier-Bold | Courier-BoldOblique |");
306         System.out.println(" Courier-Oblique | Courier |");
307         System.out.println(" Helvetica-Bold | Helvetica-BoldOblique |");
308         System.out.println(" Helvetica-Oblique | Helvetica | Symbol |");
309         System.out.println(" Times-Bold | Times-BoldItalic |");
310         System.out.println(" Times-Italic | Times-Roman |");
311         System.out.println(" ZapfDingbats > ]\n\n");
312         System.exit(0);
313     }
314
315     return font;
316     }
317
318
319     // Given a character, eg 'A', format it as "U+0041"
320
//
321
private static String JavaDoc toHex(char c)
322     {
323         String JavaDoc s = "0000" + Integer.toHexString((int)c).toUpperCase();
324     return "U+"+s.substring(s.length()-4);
325     }
326 }
327
Popular Tags