Original 2.4
[marc4j.git] / src / org / marc4j / converter / impl / Iso5426ToUnicode.java
1 // $Id: Iso5426ToUnicode.java,v 1.3 2008/10/17 06:47:06 haschart Exp $\r
2 /**\r
3  * Copyright (C) 2002 Bas  Peters  (mail@bpeters.com)\r
4  * Copyright (C) 2002 Yves Pratter (ypratter@club-internet.fr)\r
5  *\r
6  * This file is part of MARC4J\r
7  *\r
8  * MARC4J is free software; you can redistribute it and/or\r
9  * modify it under the terms of the GNU Lesser General Public \r
10  * License as published by the Free Software Foundation; either \r
11  * version 2.1 of the License, or (at your option) any later version.\r
12  *\r
13  * MARC4J is distributed in the hope that it will be useful,\r
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
16  * Lesser General Public License for more details.\r
17  *\r
18  * You should have received a copy of the GNU Lesser General Public \r
19  * License along with MARC4J; if not, write to the Free Software\r
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
21  */\r
22 package org.marc4j.converter.impl;\r
23 \r
24 import org.marc4j.converter.CharConverter;\r
25 \r
26 /**\r
27  * <p>\r
28  * A utility to convert UNIMARC data to UCS/Unicode.\r
29  * </p>\r
30  * \r
31  * @author Bas Peters\r
32  * @author Yves Pratter\r
33  * @version $Revision: 1.3 $\r
34  */\r
35 public class Iso5426ToUnicode extends CharConverter {\r
36 \r
37   /**\r
38    * <p>\r
39    * Converts UNIMARC (ISO 5426 charset) data to UCS/Unicode.\r
40    * </p>\r
41    * \r
42    * @param data - the UNIMARC data in an array of char\r
43    * @return {@link String}- the UCS/Unicode data\r
44    */\r
45   public String convert(char data[]) {\r
46     StringBuffer sb = new StringBuffer();\r
47 \r
48     for (int i = 0; i < data.length; i++) {\r
49       char c = data[i];\r
50       int len = data.length;\r
51       if (isAscii(c))\r
52         sb.append(c);\r
53       else if (isCombining(c) && hasNext(i, len)) {\r
54         char d = getCombiningChar(c * 256 + data[i + 1]);\r
55         if (d != 0) {\r
56           sb.append(d);\r
57           i++;\r
58         } else {\r
59           sb.append(getChar(c));\r
60         }\r
61       } else\r
62         sb.append(getChar(c));\r
63     }\r
64     return sb.toString();\r
65   }\r
66 \r
67   private boolean hasNext(int pos, int len) {\r
68     if (pos < (len - 1))\r
69       return true;\r
70     return false;\r
71   }\r
72 \r
73   private boolean isAscii(int i) {\r
74     if (i >= 0x00 && i <= 0x7F)\r
75       return true;\r
76     return false;\r
77   }\r
78 \r
79   private boolean isCombining(int i) {\r
80     //  if (i > 0xE0 && i < 0xFF)\r
81     if (i >= 0xC0 && i <= 0xDF)\r
82       return true;\r
83     return false;\r
84   }\r
85 \r
86   // Source : http://www.itscj.ipsj.or.jp/ISO-IR/053.pdf\r
87   private char getChar(int i) {\r
88     switch (i) {\r
89     case 0xA1:\r
90       return 0x00A1; // 2/1 inverted exclamation mark\r
91     case 0xA2:\r
92       return 0x201C; // 2/2 left low double quotation mark\r
93     case 0xA3:\r
94       return 0x00A3; // 2/3 pound sign\r
95     case 0xA4:\r
96       return 0x0024; // 2/4 dollar sign\r
97     case 0xA5:\r
98       return 0x00A5; // 2/5 yen sign\r
99     case 0xA6:\r
100       return 0x2020; // 2/6 single dagger\r
101     case 0xA7:\r
102       return 0x00A7; // 2/7 paragraph (section)\r
103     case 0xA8:\r
104       return 0x2032; // 2/8 prime\r
105     case 0xA9:\r
106       return 0x2018; // 2/9 left high single quotation mark\r
107     case 0xAA:\r
108       return 0x201C; // 2/10 left high double quotation mark\r
109     case 0xAB:\r
110       return 0x00AB; // 2/11 left angle quotation mark\r
111     case 0xAC:\r
112       return 0x266D; // 2/12 music flat\r
113     case 0xAD:\r
114       return 0x00A9; // 2/13 copyright sign\r
115     case 0xAE:\r
116       return 0x2117; // 2/14 sound recording copyright sign\r
117     case 0xAF:\r
118       return 0x00AE; // 2/15 trade mark sign\r
119 \r
120     case 0xB0:\r
121       return 0x0639; // 3/0 ayn [ain]\r
122     case 0xB1:\r
123       return 0x0623; // 3/1 alif/hamzah [alef with hamza above]\r
124     case 0xB2:\r
125       return 0x2018; // 3/2 left low single quotation mark\r
126     // 3/3 (this position shall not be used)\r
127     // 3/4 (this position shall not be used)\r
128     // 3/5 (this position shall not be used)\r
129     case 0xB6:\r
130       return 0x2021; // 3/6 double dagger\r
131     case 0xB7:\r
132       return 0x00B7; // 3/7 middle dot\r
133     case 0xB8:\r
134       return 0x2033; // 3/8 double prime\r
135     case 0xB9:\r
136       return 0x2019; // 3/9 right high single quotation mark\r
137     case 0xBA:\r
138       return 0x201D; // 3/10 right high double quotation mark\r
139     case 0xBB:\r
140       return 0x00BB; // 3/11 right angle quotation mark\r
141     case 0xBC:\r
142       return 0x266F; // 3/12 musical sharp\r
143     case 0xBD:\r
144       return 0x02B9; // 3/13 mjagkij znak\r
145     case 0xBE:\r
146       return 0x02BA; // 3/14 tverdyj znak\r
147     case 0xBF:\r
148       return 0x00BF; // 3/15 inverted question mark\r
149 \r
150     // 4/0 to 5/15 diacritic characters\r
151 \r
152     // 6/0 (this position shall not be used)\r
153     case 0xE1:\r
154       return 0x00C6; // 6/1 CAPITAL DIPHTHONG A WITH E\r
155     case 0xE2:\r
156       return 0x0110; // 6/2 CAPITAL LETTER D WITH STROKE\r
157     // 6/3 (this position shall not be used)\r
158     // 6/4 (this position shall not be used)\r
159     // 6/5 (this position shall not be used)\r
160     case 0xE6:\r
161       return 0x0132; // 6/6 CAPITAL LETTER IJ\r
162     // 6/7 (this position shall not be used)\r
163     case 0xE8:\r
164       return 0x0141; // 6/8 CAPITAL LETTER L WITH STROKE\r
165     case 0xE9:\r
166       return 0x00D8; // 6/9 CAPITAL LETTER O WITH SOLIDUS [oblique stroke]\r
167     case 0xEA:\r
168       return 0x0152; // 6/10 CAPITAL DIPHTONG OE\r
169     // 6/11 (this position shall not be used)\r
170     case 0xEC:\r
171       return 0x00DE; // 6/12 CAPITAL LETTER THORN\r
172     // 6/13 (this position shall not be used)\r
173     // 6/14 (this position shall not be used)\r
174     // 6/15 (this position shall not be used)\r
175 \r
176     // 7/0 (this position shall not be used)\r
177     case 0xF1:\r
178       return 0x00E6; // 7/1 small diphthong a with e\r
179     // 7/4 (this position shall not be used)\r
180     case 0xF5:\r
181       return 0x0131; // 7/5 small letter i without dot\r
182     case 0xF6:\r
183       return 0x0133; // 7/6 small letter ij\r
184     // 7/7 (this position shall not be used)\r
185     case 0xF8:\r
186       return 0x0142; // 7/8 small letter l with stroke\r
187     case 0xF9:\r
188       return 0x00F8; // 7/9 small letter o with solidus (oblique stroke)\r
189     case 0xFA:\r
190       return 0x0153; // 7/10 small diphtong oe\r
191     case 0xFB:\r
192       return 0x00DF; // 7/11 small letter sharp s\r
193     case 0xFC:\r
194       return 0x00FE; // 7/12 small letter thorn\r
195     // 7/13 (this position shall not be used)\r
196     // 7/14 (this position shall not be used)\r
197     default:\r
198       return (char) i;\r
199     }\r
200   }\r
201 \r
202   private char getCombiningChar(int i) {\r
203     switch (i) {\r
204     // 4/0 low rising tone mark\r
205     case 0xC041:\r
206       return 0x1EA2; // CAPITAL A WITH HOOK ABOVE\r
207     case 0xC045:\r
208       return 0x1EBA; // CAPITAL E WITH HOOK ABOVE\r
209     case 0xC049:\r
210       return 0x1EC8; // CAPITAL I WITH HOOK ABOVE\r
211     case 0xC04F:\r
212       return 0x1ECE; // CAPITAL O WITH HOOK ABOVE\r
213     case 0xC055:\r
214       return 0x1EE6; // CAPITAL U WITH HOOK ABOVE\r
215     case 0xC059:\r
216       return 0x1EF6; // CAPITAL Y WITH HOOK ABOVE\r
217     case 0xC061:\r
218       return 0x1EA3; // small a with hook above\r
219     case 0xC065:\r
220       return 0x1EBB; // small e with hook above\r
221     case 0xC069:\r
222       return 0x1EC9; // small i with hook above\r
223     case 0xC06F:\r
224       return 0x1ECF; // small o with hook above\r
225     case 0xC075:\r
226       return 0x1EE7; // small u with hook above\r
227     case 0xC079:\r
228       return 0x1EF7; // small y with hook above\r
229 \r
230     // 4/1 grave accent\r
231     case 0xC141:\r
232       return 0x00C0; // CAPITAL A WITH GRAVE ACCENT\r
233     case 0xC145:\r
234       return 0x00C8; // CAPITAL E WITH GRAVE ACCENT\r
235     case 0xC149:\r
236       return 0x00CC; // CAPITAL I WITH GRAVE ACCENT\r
237     case 0xC14F:\r
238       return 0x00D2; // CAPITAL O WITH GRAVE ACCENT\r
239     case 0xC155:\r
240       return 0x00D9; // CAPITAL U WITH GRAVE ACCENT\r
241     case 0xC157:\r
242       return 0x1E80; // CAPITAL W WITH GRAVE\r
243     case 0xC159:\r
244       return 0x1EF2; // CAPITAL Y WITH GRAVE\r
245     case 0xC161:\r
246       return 0x00E0; // small a with grave accent\r
247     case 0xC165:\r
248       return 0x00E8; // small e with grave accent\r
249     case 0xC169:\r
250       return 0x00EC; // small i with grave accent\r
251     case 0xC16F:\r
252       return 0x00F2; // small o with grave accent\r
253     case 0xC175:\r
254       return 0x00F9; // small u with grave accent\r
255     case 0xC177:\r
256       return 0x1E81; // small w with grave\r
257     case 0xC179:\r
258       return 0x1EF3; // small y with grave\r
259 \r
260     // 4/2 acute accent\r
261     case 0xC241:\r
262       return 0x00C1; // CAPITAL A WITH ACUTE ACCENT\r
263     case 0xC243:\r
264       return 0x0106; // CAPITAL C WITH ACUTE ACCENT\r
265     case 0xC245:\r
266       return 0x00C9; // CAPITAL E WITH ACUTE ACCENT\r
267     case 0xC247:\r
268       return 0x01F4; // CAPITAL G WITH ACUTE\r
269     case 0xC249:\r
270       return 0x00CD; // CAPITAL I WITH ACUTE ACCENT\r
271     case 0xC24B:\r
272       return 0x1E30; // CAPITAL K WITH ACUTE\r
273     case 0xC24C:\r
274       return 0x0139; // CAPITAL L WITH ACUTE ACCENT\r
275     case 0xC24D:\r
276       return 0x1E3E; // CAPITAL M WITH ACUTE\r
277     case 0xC24E:\r
278       return 0x0143; // CAPITAL N WITH ACUTE ACCENT\r
279     case 0xC24F:\r
280       return 0x00D3; // CAPITAL O WITH ACUTE ACCENT\r
281     case 0xC250:\r
282       return 0x1E54; // CAPITAL P WITH ACUTE\r
283     case 0xC252:\r
284       return 0x0154; // CAPITAL R WITH ACUTE ACCENT\r
285     case 0xC253:\r
286       return 0x015A; // CAPITAL S WITH ACUTE ACCENT\r
287     case 0xC255:\r
288       return 0x00DA; // CAPITAL U WITH ACUTE ACCENT\r
289     case 0xC257:\r
290       return 0x1E82; // CAPITAL W WITH ACUTE\r
291     case 0xC259:\r
292       return 0x00DD; // CAPITAL Y WITH ACUTE ACCENT\r
293     case 0xC25A:\r
294       return 0x0179; // CAPITAL Z WITH ACUTE ACCENT\r
295     case 0xC261:\r
296       return 0x00E1; // small a with acute accent\r
297     case 0xC263:\r
298       return 0x0107; // small c with acute accent\r
299     case 0xC265:\r
300       return 0x00E9; // small e with acute accent\r
301     case 0xC267:\r
302       return 0x01F5; // small g with acute\r
303     case 0xC269:\r
304       return 0x00ED; // small i with acute accent\r
305     case 0xC26B:\r
306       return 0x1E31; // small k with acute\r
307     case 0xC26C:\r
308       return 0x013A; // small l with acute accent\r
309     case 0xC26D:\r
310       return 0x1E3F; // small m with acute\r
311     case 0xC26E:\r
312       return 0x0144; // small n with acute accent\r
313     case 0xC26F:\r
314       return 0x00F3; // small o with acute accent\r
315     case 0xC270:\r
316       return 0x1E55; // small p with acute\r
317     case 0xC272:\r
318       return 0x0155; // small r with acute accent\r
319     case 0xC273:\r
320       return 0x015B; // small s with acute accent\r
321     case 0xC275:\r
322       return 0x00FA; // small u with acute accent\r
323     case 0xC277:\r
324       return 0x1E83; // small w with acute\r
325     case 0xC279:\r
326       return 0x00FD; // small y with acute accent\r
327     case 0xC27A:\r
328       return 0x017A; // small z with acute accent\r
329     case 0xC2E1:\r
330       return 0x01FC; // CAPITAL AE WITH ACUTE\r
331     case 0xC2F1:\r
332       return 0x01FD; // small ae with acute\r
333 \r
334     // 4/3 circumflex accent\r
335     case 0xC341:\r
336       return 0x00C2; // CAPITAL A WITH CIRCUMFLEX ACCENT\r
337     case 0xC343:\r
338       return 0x0108; // CAPITAL C WITH CIRCUMFLEX\r
339     case 0xC345:\r
340       return 0x00CA; // CAPITAL E WITH CIRCUMFLEX ACCENT\r
341     case 0xC347:\r
342       return 0x011C; // CAPITAL G WITH CIRCUMFLEX\r
343     case 0xC348:\r
344       return 0x0124; // CAPITAL H WITH CIRCUMFLEX\r
345     case 0xC349:\r
346       return 0x00CE; // CAPITAL I WITH CIRCUMFLEX ACCENT\r
347     case 0xC34A:\r
348       return 0x0134; // CAPITAL J WITH CIRCUMFLEX\r
349     case 0xC34F:\r
350       return 0x00D4; // CAPITAL O WITH CIRCUMFLEX ACCENT\r
351     case 0xC353:\r
352       return 0x015C; // CAPITAL S WITH CIRCUMFLEX\r
353     case 0xC355:\r
354       return 0x00DB; // CAPITAL U WITH CIRCUMFLEX\r
355     case 0xC357:\r
356       return 0x0174; // CAPITAL W WITH CIRCUMFLEX\r
357     case 0xC359:\r
358       return 0x0176; // CAPITAL Y WITH CIRCUMFLEX\r
359     case 0xC35A:\r
360       return 0x1E90; // CAPITAL Z WITH CIRCUMFLEX\r
361     case 0xC361:\r
362       return 0x00E2; // small a with circumflex accent\r
363     case 0xC363:\r
364       return 0x0109; // small c with circumflex\r
365     case 0xC365:\r
366       return 0x00EA; // small e with circumflex accent\r
367     case 0xC367:\r
368       return 0x011D; // small g with circumflex\r
369     case 0xC368:\r
370       return 0x0125; // small h with circumflex\r
371     case 0xC369:\r
372       return 0x00EE; // small i with circumflex accent\r
373     case 0xC36A:\r
374       return 0x0135; // small j with circumflex\r
375     case 0xC36F:\r
376       return 0x00F4; // small o with circumflex accent\r
377     case 0xC373:\r
378       return 0x015D; // small s with circumflex\r
379     case 0xC375:\r
380       return 0x00FB; // small u with circumflex\r
381     case 0xC377:\r
382       return 0x0175; // small w with circumflex\r
383     case 0xC379:\r
384       return 0x0177; // small y with circumflex\r
385     case 0xC37A:\r
386       return 0x1E91; // small z with circumflex\r
387 \r
388     // 4/4 tilde\r
389     case 0xC441:\r
390       return 0x00C3; // CAPITAL A WITH TILDE\r
391     case 0xC445:\r
392       return 0x1EBC; // CAPITAL E WITH TILDE\r
393     case 0xC449:\r
394       return 0x0128; // CAPITAL I WITH TILDE\r
395     case 0xC44E:\r
396       return 0x00D1; // CAPITAL N WITH TILDE\r
397     case 0xC44F:\r
398       return 0x00D5; // CAPITAL O WITH TILDE\r
399     case 0xC455:\r
400       return 0x0168; // CAPITAL U WITH TILDE\r
401     case 0xC456:\r
402       return 0x1E7C; // CAPITAL V WITH TILDE\r
403     case 0xC459:\r
404       return 0x1EF8; // CAPITAL Y WITH TILDE\r
405     case 0xC461:\r
406       return 0x00E3; // small a with tilde\r
407     case 0xC465:\r
408       return 0x1EBD; // small e with tilde\r
409     case 0xC469:\r
410       return 0x0129; // small i with tilde\r
411     case 0xC46E:\r
412       return 0x00F1; // small n with tilde\r
413     case 0xC46F:\r
414       return 0x00F5; // small o with tilde\r
415     case 0xC475:\r
416       return 0x0169; // small u with tilde\r
417     case 0xC476:\r
418       return 0x1E7D; // small v with tilde\r
419     case 0xC479:\r
420       return 0x1EF9; // small y with tilde\r
421 \r
422     // 4/5 macron\r
423     case 0xC541:\r
424       return 0x0100; // CAPITAL A WITH MACRON\r
425     case 0xC545:\r
426       return 0x0112; // CAPITAL E WITH MACRON\r
427     case 0xC547:\r
428       return 0x1E20; // CAPITAL G WITH MACRON\r
429     case 0xC549:\r
430       return 0x012A; // CAPITAL I WITH MACRON\r
431     case 0xC54F:\r
432       return 0x014C; // CAPITAL O WITH MACRON\r
433     case 0xC555:\r
434       return 0x016A; // CAPITAL U WITH MACRON\r
435     case 0xC561:\r
436       return 0x0101; // small a with macron\r
437     case 0xC565:\r
438       return 0x0113; // small e with macron\r
439     case 0xC567:\r
440       return 0x1E21; // small g with macron\r
441     case 0xC569:\r
442       return 0x012B; // small i with macron\r
443     case 0xC56F:\r
444       return 0x014D; // small o with macron\r
445     case 0xC575:\r
446       return 0x016B; // small u with macron\r
447     case 0xC5E1:\r
448       return 0x01E2; // CAPITAL AE WITH MACRON\r
449     case 0xC5F1:\r
450       return 0x01E3; // small ae with macron\r
451 \r
452     // 4/6 breve\r
453     case 0xC641:\r
454       return 0x0102; // CAPITAL A WITH BREVE\r
455     case 0xC645:\r
456       return 0x0114; // CAPITAL E WITH BREVE\r
457     case 0xC647:\r
458       return 0x011E; // CAPITAL G WITH BREVE\r
459     case 0xC649:\r
460       return 0x012C; // CAPITAL I WITH BREVE\r
461     case 0xC64F:\r
462       return 0x014E; // CAPITAL O WITH BREVE\r
463     case 0xC655:\r
464       return 0x016C; // CAPITAL U WITH BREVE\r
465     case 0xC661:\r
466       return 0x0103; // small a with breve\r
467     case 0xC665:\r
468       return 0x0115; // small e with breve\r
469     case 0xC667:\r
470       return 0x011F; // small g with breve\r
471     case 0xC669:\r
472       return 0x012D; // small i with breve\r
473     case 0xC66F:\r
474       return 0x014F; // small o with breve\r
475     case 0xC675:\r
476       return 0x016D; // small u with breve\r
477 \r
478     // 4/7 dot above\r
479     case 0xC742:\r
480       return 0x1E02; // CAPITAL B WITH DOT ABOVE\r
481     case 0xC743:\r
482       return 0x010A; // CAPITAL C WITH DOT ABOVE\r
483     case 0xC744:\r
484       return 0x1E0A; // CAPITAL D WITH DOT ABOVE\r
485     case 0xC745:\r
486       return 0x0116; // CAPITAL E WITH DOT ABOVE\r
487     case 0xC746:\r
488       return 0x1E1E; // CAPITAL F WITH DOT ABOVE\r
489     case 0xC747:\r
490       return 0x0120; // CAPITAL G WITH DOT ABOVE\r
491     case 0xC748:\r
492       return 0x1E22; // CAPITAL H WITH DOT ABOVE\r
493     case 0xC749:\r
494       return 0x0130; // CAPITAL I WITH DOT ABOVE\r
495     case 0xC74D:\r
496       return 0x1E40; // CAPITAL M WITH DOT ABOVE\r
497     case 0xC74E:\r
498       return 0x1E44; // CAPITAL N WITH DOT ABOVE\r
499     case 0xC750:\r
500       return 0x1E56; // CAPITAL P WITH DOT ABOVE\r
501     case 0xC752:\r
502       return 0x1E58; // CAPITAL R WITH DOT ABOVE\r
503     case 0xC753:\r
504       return 0x1E60; // CAPITAL S WITH DOT ABOVE\r
505     case 0xC754:\r
506       return 0x1E6A; // CAPITAL T WITH DOT ABOVE\r
507     case 0xC757:\r
508       return 0x1E86; // CAPITAL W WITH DOT ABOVE\r
509     case 0xC758:\r
510       return 0x1E8A; // CAPITAL X WITH DOT ABOVE\r
511     case 0xC759:\r
512       return 0x1E8E; // CAPITAL Y WITH DOT ABOVE\r
513     case 0xC75A:\r
514       return 0x017B; // CAPITAL Z WITH DOT ABOVE\r
515     case 0xC762:\r
516       return 0x1E03; // small b with dot above\r
517     case 0xC763:\r
518       return 0x010B; // small c with dot above\r
519     case 0xC764:\r
520       return 0x1E0B; // small d with dot above\r
521     case 0xC765:\r
522       return 0x0117; // small e with dot above\r
523     case 0xC766:\r
524       return 0x1E1F; // small f with dot above\r
525     case 0xC767:\r
526       return 0x0121; // small g with dot above\r
527     case 0xC768:\r
528       return 0x1E23; // small h with dot above\r
529     case 0xC76D:\r
530       return 0x1E41; // small m with dot above\r
531     case 0xC76E:\r
532       return 0x1E45; // small n with dot above\r
533     case 0xC770:\r
534       return 0x1E57; // small p with dot above\r
535     case 0xC772:\r
536       return 0x1E59; // small r with dot above\r
537     case 0xC773:\r
538       return 0x1E61; // small s with dot above\r
539     case 0xC774:\r
540       return 0x1E6B; // small t with dot above\r
541     case 0xC777:\r
542       return 0x1E87; // small w with dot above\r
543     case 0xC778:\r
544       return 0x1E8B; // small x with dot above\r
545     case 0xC779:\r
546       return 0x1E8F; // small y with dot above\r
547     case 0xC77A:\r
548       return 0x017C; // small z with dot above\r
549 \r
550     // 4/8 trema, diaresis\r
551     case 0xC820:\r
552       return 0x00A8; // diaeresis\r
553     case 0xC841:\r
554       return 0x00C4; // CAPITAL A WITH DIAERESIS\r
555     case 0xC845:\r
556       return 0x00CB; // CAPITAL E WITH DIAERESIS\r
557     case 0xC848:\r
558       return 0x1E26; // CAPITAL H WITH DIAERESIS\r
559     case 0xC849:\r
560       return 0x00CF; // CAPITAL I WITH DIAERESIS\r
561     case 0xC84F:\r
562       return 0x00D6; // CAPITAL O WITH DIAERESIS\r
563     case 0xC855:\r
564       return 0x00DC; // CAPITAL U WITH DIAERESIS\r
565     case 0xC857:\r
566       return 0x1E84; // CAPITAL W WITH DIAERESIS\r
567     case 0xC858:\r
568       return 0x1E8C; // CAPITAL X WITH DIAERESIS\r
569     case 0xC859:\r
570       return 0x0178; // CAPITAL Y WITH DIAERESIS\r
571     case 0xC861:\r
572       return 0x00E4; // small a with diaeresis\r
573     case 0xC865:\r
574       return 0x00EB; // small e with diaeresis\r
575     case 0xC868:\r
576       return 0x1E27; // small h with diaeresis\r
577     case 0xC869:\r
578       return 0x00EF; // small i with diaeresis\r
579     case 0xC86F:\r
580       return 0x00F6; // small o with diaeresis\r
581     case 0xC874:\r
582       return 0x1E97; // small t with diaeresis\r
583     case 0xC875:\r
584       return 0x00FC; // small u with diaeresis\r
585     case 0xC877:\r
586       return 0x1E85; // small w with diaeresis\r
587     case 0xC878:\r
588       return 0x1E8D; // small x with diaeresis\r
589     case 0xC879:\r
590       return 0x00FF; // small y with diaeresis\r
591 \r
592     // 4/9 umlaut\r
593     case 0xC920:\r
594       return 0x00A8; // [diaeresis]\r
595 \r
596     // 4/10 circle above\r
597     case 0xCA41:\r
598       return 0x00C5; // CAPITAL A WITH RING ABOVE\r
599     case 0xCAAD:\r
600       return 0x016E; // CAPITAL U WITH RING ABOVE\r
601     case 0xCA61:\r
602       return 0x00E5; // small a with ring above\r
603     case 0xCA75:\r
604       return 0x016F; // small u with ring above\r
605     case 0xCA77:\r
606       return 0x1E98; // small w with ring above\r
607     case 0xCA79:\r
608       return 0x1E99; // small y with ring above\r
609 \r
610     // 4/11 high comma off centre\r
611 \r
612     // 4/12 inverted high comma centred\r
613 \r
614     // 4/13 double acute accent\r
615     case 0xCD4F:\r
616       return 0x0150; // CAPITAL O WITH DOUBLE ACUTE\r
617     case 0xCD55:\r
618       return 0x0170; // CAPITAL U WITH DOUBLE ACUTE\r
619     case 0xCD6F:\r
620       return 0x0151; // small o with double acute\r
621     case 0xCD75:\r
622       return 0x0171; // small u with double acute\r
623 \r
624     // 4/14 horn\r
625     case 0xCE54:\r
626       return 0x01A0; // LATIN CAPITAL LETTER O WITH HORN\r
627     case 0xCE55:\r
628       return 0x01AF; // LATIN CAPITAL LETTER U WITH HORN\r
629     case 0xCE74:\r
630       return 0x01A1; // latin small letter o with horn\r
631     case 0xCE75:\r
632       return 0x01B0; // latin small letter u with horn\r
633 \r
634     // 4/15 caron (hacek)\r
635     case 0xCF41:\r
636       return 0x01CD; // CAPITAL A WITH CARON\r
637     case 0xCF43:\r
638       return 0x010C; // CAPITAL C WITH CARON\r
639     case 0xCF44:\r
640       return 0x010E; // CAPITAL D WITH CARON\r
641     case 0xCF45:\r
642       return 0x011A; // CAPITAL E WITH CARON\r
643     case 0xCF47:\r
644       return 0x01E6; // CAPITAL G WITH CARON\r
645     case 0xCF49:\r
646       return 0x01CF; // CAPITAL I WITH CARON\r
647     case 0xCF4B:\r
648       return 0x01E8; // CAPITAL K WITH CARON\r
649     case 0xCF4C:\r
650       return 0x013D; // CAPITAL L WITH CARON\r
651     case 0xCF4E:\r
652       return 0x0147; // CAPITAL N WITH CARON\r
653     case 0xCF4F:\r
654       return 0x01D1; // CAPITAL O WITH CARON\r
655     case 0xCF52:\r
656       return 0x0158; // CAPITAL R WITH CARON\r
657     case 0xCF53:\r
658       return 0x0160; // CAPITAL S WITH CARON\r
659     case 0xCF54:\r
660       return 0x0164; // CAPITAL T WITH CARON\r
661     case 0xCF55:\r
662       return 0x01D3; // CAPITAL U WITH CARON\r
663     case 0xCF5A:\r
664       return 0x017D; // CAPITAL Z WITH CARON\r
665     case 0xCF61:\r
666       return 0x01CE; // small a with caron\r
667     case 0xCF63:\r
668       return 0x010D; // small c with caron\r
669     case 0xCF64:\r
670       return 0x010F; // small d with caron\r
671     case 0xCF65:\r
672       return 0x011B; // small e with caron\r
673     case 0xCF67:\r
674       return 0x01E7; // small g with caron\r
675     case 0xCF69:\r
676       return 0x01D0; // small i with caron\r
677     case 0xCF6A:\r
678       return 0x01F0; // small j with caron\r
679     case 0xCF6B:\r
680       return 0x01E9; // small k with caron\r
681     case 0xCF6C:\r
682       return 0x013E; // small l with caron\r
683     case 0xCF6E:\r
684       return 0x0148; // small n with caron\r
685     case 0xCF6F:\r
686       return 0x01D2; // small o with caron\r
687     case 0xCF72:\r
688       return 0x0159; // small r with caron\r
689     case 0xCF73:\r
690       return 0x0161; // small s with caron\r
691     case 0xCF74:\r
692       return 0x0165; // small t with caron\r
693     case 0xCF75:\r
694       return 0x01D4; // small u with caron\r
695     case 0xCF7A:\r
696       return 0x017E; // small z with caron\r
697 \r
698     // 5/0 cedilla\r
699     case 0xD020:\r
700       return 0x00B8; // cedilla\r
701     case 0xD043:\r
702       return 0x00C7; // CAPITAL C WITH CEDILLA\r
703     case 0xD044:\r
704       return 0x1E10; // CAPITAL D WITH CEDILLA\r
705     case 0xD047:\r
706       return 0x0122; // CAPITAL G WITH CEDILLA\r
707     case 0xD048:\r
708       return 0x1E28; // CAPITAL H WITH CEDILLA\r
709     case 0xD04B:\r
710       return 0x0136; // CAPITAL K WITH CEDILLA\r
711     case 0xD04C:\r
712       return 0x013B; // CAPITAL L WITH CEDILLA\r
713     case 0xD04E:\r
714       return 0x0145; // CAPITAL N WITH CEDILLA\r
715     case 0xD052:\r
716       return 0x0156; // CAPITAL R WITH CEDILLA\r
717     case 0xD053:\r
718       return 0x015E; // CAPITAL S WITH CEDILLA\r
719     case 0xD054:\r
720       return 0x0162; // CAPITAL T WITH CEDILLA\r
721     case 0xD063:\r
722       return 0x00E7; // small c with cedilla\r
723     case 0xD064:\r
724       return 0x1E11; // small d with cedilla\r
725     case 0xD067:\r
726       return 0x0123; // small g with cedilla\r
727     case 0xD068:\r
728       return 0x1E29; // small h with cedilla\r
729     case 0xD06B:\r
730       return 0x0137; // small k with cedilla\r
731     case 0xD06C:\r
732       return 0x013C; // small l with cedilla\r
733     case 0xD06E:\r
734       return 0x0146; // small n with cedilla\r
735     case 0xD072:\r
736       return 0x0157; // small r with cedilla\r
737     case 0xD073:\r
738       return 0x015F; // small s with cedilla\r
739     case 0xD074:\r
740       return 0x0163; // small t with cedilla\r
741 \r
742     // 5/1 rude\r
743 \r
744     // 5/2 hook to left\r
745 \r
746     // 5/3 ogonek (hook to right)\r
747     case 0xD320:\r
748       return 0x02DB; // ogonek\r
749     case 0xD341:\r
750       return 0x0104; // CAPITAL A WITH OGONEK\r
751     case 0xD345:\r
752       return 0x0118; // CAPITAL E WITH OGONEK\r
753     case 0xD349:\r
754       return 0x012E; // CAPITAL I WITH OGONEK\r
755     case 0xD34F:\r
756       return 0x01EA; // CAPITAL O WITH OGONEK\r
757     case 0xD355:\r
758       return 0x0172; // CAPITAL U WITH OGONEK\r
759     case 0xD361:\r
760       return 0x0105; // small a with ogonek\r
761     case 0xD365:\r
762       return 0x0119; // small e with ogonek\r
763     case 0xD369:\r
764       return 0x012F; // small i with ogonek\r
765     case 0xD36F:\r
766       return 0x01EB; // small o with ogonek\r
767     case 0xD375:\r
768       return 0x0173; // small u with ogonek\r
769 \r
770     // 5/4 circle below\r
771     case 0xD441:\r
772       return 0x1E00; // CAPITAL A WITH RING BELOW\r
773     case 0xD461:\r
774       return 0x1E01; // small a with ring below\r
775 \r
776     // 5/5 half circle below\r
777     case 0xF948:\r
778       return 0x1E2A; // CAPITAL H WITH BREVE BELOW\r
779     case 0xF968:\r
780       return 0x1E2B; // small h with breve below\r
781 \r
782     // 5/6 dot below\r
783     case 0xD641:\r
784       return 0x1EA0; // CAPITAL A WITH DOT BELOW\r
785     case 0xD642:\r
786       return 0x1E04; // CAPITAL B WITH DOT BELOW\r
787     case 0xD644:\r
788       return 0x1E0C; // CAPITAL D WITH DOT BELOW\r
789     case 0xD645:\r
790       return 0x1EB8; // CAPITAL E WITH DOT BELOW\r
791     case 0xD648:\r
792       return 0x1E24; // CAPITAL H WITH DOT BELOW\r
793     case 0xD649:\r
794       return 0x1ECA; // CAPITAL I WITH DOT BELOW\r
795     case 0xD64B:\r
796       return 0x1E32; // CAPITAL K WITH DOT BELOW\r
797     case 0xD64C:\r
798       return 0x1E36; // CAPITAL L WITH DOT BELOW\r
799     case 0xD64D:\r
800       return 0x1E42; // CAPITAL M WITH DOT BELOW\r
801     case 0xD64E:\r
802       return 0x1E46; // CAPITAL N WITH DOT BELOW\r
803     case 0xD64F:\r
804       return 0x1ECC; // CAPITAL O WITH DOT BELOW\r
805     case 0xD652:\r
806       return 0x1E5A; // CAPITAL R WITH DOT BELOW\r
807     case 0xD653:\r
808       return 0x1E62; // CAPITAL S WITH DOT BELOW\r
809     case 0xD654:\r
810       return 0x1E6C; // CAPITAL T WITH DOT BELOW\r
811     case 0xD655:\r
812       return 0x1EE4; // CAPITAL U WITH DOT BELOW\r
813     case 0xD656:\r
814       return 0x1E7E; // CAPITAL V WITH DOT BELOW\r
815     case 0xD657:\r
816       return 0x1E88; // CAPITAL W WITH DOT BELOW\r
817     case 0xD659:\r
818       return 0x1EF4; // CAPITAL Y WITH DOT BELOW\r
819     case 0xD65A:\r
820       return 0x1E92; // CAPITAL Z WITH DOT BELOW\r
821     case 0xD661:\r
822       return 0x1EA1; // small a with dot below\r
823     case 0xD662:\r
824       return 0x1E05; // small b with dot below\r
825     case 0xD664:\r
826       return 0x1E0D; // small d with dot below\r
827     case 0xD665:\r
828       return 0x1EB9; // small e with dot below\r
829     case 0xD668:\r
830       return 0x1E25; // small h with dot below\r
831     case 0xD669:\r
832       return 0x1ECB; // small i with dot below\r
833     case 0xD66B:\r
834       return 0x1E33; // small k with dot below\r
835     case 0xD66C:\r
836       return 0x1E37; // small l with dot below\r
837     case 0xD66D:\r
838       return 0x1E43; // small m with dot below\r
839     case 0xD66E:\r
840       return 0x1E47; // small n with dot below\r
841     case 0xD66F:\r
842       return 0x1ECD; // small o with dot below\r
843     case 0xD672:\r
844       return 0x1E5B; // small r with dot below\r
845     case 0xD673:\r
846       return 0x1E63; // small s with dot below\r
847     case 0xD674:\r
848       return 0x1E6D; // small t with dot below\r
849     case 0xD675:\r
850       return 0x1EE5; // small u with dot below\r
851     case 0xD676:\r
852       return 0x1E7F; // small v with dot below\r
853     case 0xD677:\r
854       return 0x1E89; // small w with dot below\r
855     case 0xD679:\r
856       return 0x1EF5; // small y with dot below\r
857     case 0xD67A:\r
858       return 0x1E93; // small z with dot below\r
859 \r
860     // 5/7 double dot below\r
861     case 0xD755:\r
862       return 0x1E72; // CAPITAL U WITH DIAERESIS BELOW\r
863     case 0xD775:\r
864       return 0x1E73; // small u with diaeresis below\r
865 \r
866     // 5/8 underline\r
867     case 0xD820:\r
868       return 0x005F; // underline\r
869 \r
870     // 5/9 double underline\r
871     case 0xD920:\r
872       return 0x2017; // double underline\r
873 \r
874     // 5/10 small low vertical bar\r
875     case 0xDA20:\r
876       return 0x02CC; // \r
877 \r
878     // 5/11 circumflex below\r
879 \r
880     // 5/12 (this position shall not be used)\r
881 \r
882     // 5/13 left half of ligature sign and of double tilde\r
883 \r
884     // 5/14 right half of ligature sign\r
885 \r
886     // 5/15 right half of double tilde\r
887 \r
888     default:\r
889       return 0;\r
890     }\r
891   }\r
892 }