[poppler] poppler/poppler: Makefile.am, 1.22, 1.23 TextOutputDev.cc, 1.19, 1.20 TextOutputDev.h, 1.11, 1.12 UnicodeCClassTables.h, NONE, 1.1 UnicodeCompTables.h, NONE, 1.1 UnicodeDecompTables.h, NONE, 1.1 UnicodeTypeTable.cc, 1.3, 1.4 UnicodeTypeTable.h, 1.2, 1.3

Kristian Høgsberg krh at kemper.freedesktop.org
Fri May 19 15:04:19 PDT 2006


Update of /cvs/poppler/poppler/poppler
In directory kemper:/tmp/cvs-serv25036/poppler

Modified Files:
	Makefile.am TextOutputDev.cc TextOutputDev.h 
	UnicodeTypeTable.cc UnicodeTypeTable.h 
Added Files:
	UnicodeCClassTables.h UnicodeCompTables.h 
	UnicodeDecompTables.h 
Log Message:
2006-05-19  Kristian Høgsberg  <krh at redhat.com>

	* TextOutputDev.h:
	* TextOutputDev.cc:
	* UnicodeTypeTable.h:
	* UnicodeTypeTable.cc:
	* UnicodeCClassTables.h:
	* UnicodeCompTables.h:
	* UnicodeDecompTables.h:
	* gen-unicode-tables.py: Patch from Ed Catmur (#2929) to convert
	search string and document text to unicode NFKC (compatibility
	composition) before matching so ligatures match correctly.



Index: Makefile.am
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Makefile.am,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- Makefile.am	8 Apr 2006 10:44:43 -0000	1.22
+++ Makefile.am	19 May 2006 22:04:17 -0000	1.23
@@ -136,6 +136,9 @@
 	UnicodeMap.h		\
 	UnicodeMapTables.h	\
 	UnicodeTypeTable.h	\
+	UnicodeCClassTables.h	\
+	UnicodeCompTables.h	\
+	UnicodeDecompTables.h	\
 	XRef.h			\
 	CharTypes.h		\
 	CompactFontTables.h	\
@@ -200,3 +203,5 @@
 	SecurityHandler.cc	\
 	UGooString.cc	 	\
 	XpdfPluginAPI.cc
+
+EXTRA_DIST = gen-unicode-tables.py

Index: TextOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/TextOutputDev.cc,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- TextOutputDev.cc	19 May 2006 19:21:59 -0000	1.19
+++ TextOutputDev.cc	19 May 2006 22:04:17 -0000	1.20
@@ -497,6 +497,9 @@
   next = NULL;
   xMin = yMin = 0;
   xMax = yMax = -1;
+  normalized = NULL;
+  normalized_len = 0;
+  normalized_idx = NULL;
 }
 
 TextLine::~TextLine() {
@@ -510,6 +513,10 @@
   gfree(text);
   gfree(edge);
   gfree(col);
+  if (normalized) {
+    gfree(normalized);
+    gfree(normalized_idx);
+  }
 }
 
 void TextLine::addWord(TextWord *word) {
@@ -2659,12 +2666,12 @@
 
   // convert the search string to uppercase
   if (!caseSensitive) {
-    s2 = (Unicode *)gmallocn(len, sizeof(Unicode));
+    s2 = unicodeNormalizeNFKC(s, len, &len, NULL);
     for (i = 0; i < len; ++i) {
-      s2[i] = unicodeToUpper(s[i]);
+      s2[i] = unicodeToUpper(s2[i]);
     }
   } else {
-    s2 = s;
+    s2 = unicodeNormalizeNFKC(s, len, &len, NULL);
   }
 
   txt = NULL;
@@ -2719,18 +2726,22 @@
 	continue;
       }
 
+      if (!line->normalized)
+	line->normalized = unicodeNormalizeNFKC(line->text, line->len, 
+						&line->normalized_len, 
+						&line->normalized_idx);
       // convert the line to uppercase
-      m = line->len;
+      m = line->normalized_len;
       if (!caseSensitive) {
 	if (m > txtSize) {
 	  txt = (Unicode *)greallocn(txt, m, sizeof(Unicode));
 	  txtSize = m;
 	}
 	for (k = 0; k < m; ++k) {
-	  txt[k] = unicodeToUpper(line->text[k]);
+	  txt[k] = unicodeToUpper(line->normalized[k]);
 	  }
 	  } else {
-	txt = line->text;
+	txt = line->normalized;
 	  }
 
       // search each position in this line
@@ -2749,28 +2760,28 @@
 	if (k == len) {
 	  switch (line->rot) {
 	  case 0:
-	    xMin1 = line->edge[j];
-	    xMax1 = line->edge[j + len];
+	    xMin1 = line->edge[line->normalized_idx[j]];
+	    xMax1 = line->edge[line->normalized_idx[j + len]];
 	    yMin1 = line->yMin;
 	    yMax1 = line->yMax;
 	    break;
 	  case 1:
 	    xMin1 = line->xMin;
 	    xMax1 = line->xMax;
-	    yMin1 = line->edge[j];
-	    yMax1 = line->edge[j + len];
+	    yMin1 = line->edge[line->normalized_idx[j]];
+	    yMax1 = line->edge[line->normalized_idx[j + len]];
 	    break;
 	  case 2:
-	    xMin1 = line->edge[j + len];
-	    xMax1 = line->edge[j];
+	    xMin1 = line->edge[line->normalized_idx[j + len]];
+	    xMax1 = line->edge[line->normalized_idx[j]];
 	    yMin1 = line->yMin;
 	    yMax1 = line->yMax;
 	    break;
 	  case 3:
 	    xMin1 = line->xMin;
 	    xMax1 = line->xMax;
-	    yMin1 = line->edge[j + len];
-	    yMax1 = line->edge[j];
+	    yMin1 = line->edge[line->normalized_idx[j + len]];
+	    yMax1 = line->edge[line->normalized_idx[j]];
 	    break;
 	  }
 	  if (backward) {
@@ -2814,8 +2825,8 @@
     }
     }
 
+  gfree(s2);
   if (!caseSensitive) {
-    gfree(s2);
     gfree(txt);
   }
 

Index: TextOutputDev.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/TextOutputDev.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- TextOutputDev.h	28 Feb 2006 23:24:59 -0000	1.11
+++ TextOutputDev.h	19 May 2006 22:04:17 -0000	1.12
@@ -240,6 +240,9 @@
   int convertedLen;		// total number of converted characters
   GBool hyphenated;		// set if last char is a hyphen
   TextLine *next;		// next line in block
+  Unicode *normalized;		// normalized form of Unicode text
+  int normalized_len;		// number of normalized Unicode chars
+  int *normalized_idx;		// indices of normalized chars into Unicode text
 
   friend class TextLineFrag;
   friend class TextBlock;

--- NEW FILE: UnicodeCClassTables.h ---
// Copied from gunidecomp.h in GLib:
// 	s/[G]_UNICODE_MAX_TABLE_INDEX/UNICODE_MAX_TABLE_INDEX/g
// 	s/[g]uchar/Unicode/g
// 	s/[g]int16/short/g
// Can be regenerated from gen-unicode-tables.pl, also in GLib, with relevant 
// Unicode data tables from ftp.unicode.org.

static const Unicode cclass_data[][256] = {
  { /* page 3, index 0 */
    230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 
    230, 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 
    220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 
    220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 
    220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, 
    220, 220, 230, 230, 230, 220, 220, 0, 230, 230, 230, 220, 220, 220, 220, 
    230, 0, 0, 0, 0, 0, 234, 234, 233, 234, 234, 233, 230, 230, 230, 230, 
    230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
[...1788 lines suppressed...]
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX
};

--- NEW FILE: UnicodeCompTables.h ---
// Copied from gunicomp.h in GLib:
// 	s/[G]_UNICODE_MAX_TABLE_INDEX/UNICODE_MAX_TABLE_INDEX/g
// 	s/[g]uint16/unsigned short/g
// 	s/[g]int16/short/g
// Can be regenerated from gen-unicode-tables.pl, also in GLib, with relevant 
// Unicode data tables from ftp.unicode.org.

#define COMPOSE_FIRST_START 1
#define COMPOSE_FIRST_SINGLE_START 147
#define COMPOSE_SECOND_START 357
#define COMPOSE_SECOND_SINGLE_START 388

#define COMPOSE_TABLE_LAST 48

static const unsigned short compose_data[][256] = {
  { /* page 0, index 0 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 148, 149, 0, 0, 1, 2, 3, 4, 5, 
    150, 6, 7, 8, 151, 9, 10, 11, 12, 13, 14, 0, 15, 16, 17, 18, 19, 20, 21, 
    22, 23, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 152, 29, 30, 31, 32, 33, 
    34, 35, 36, 37, 38, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 153, 154, 
    50, 155, 0, 0, 51, 0, 0, 0, 0, 156, 0, 0, 0, 0, 52, 53, 157, 0, 158, 0, 
    0, 0, 54, 0, 0, 0, 0, 0, 55, 0, 159, 160, 56, 161, 0, 0, 57, 0, 0, 0, 0, 
    162, 0, 0, 0, 0, 58, 59, 163, 0, 164, 0, 0, 0, 60, 0, 0, 0
  },
  { /* page 1, index 1 */
    0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 65, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 166, 0, 
    0, 0, 0, 167, 168, 0, 0, 0, 0, 0, 0, 169, 170, 171, 172, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 
    68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 0, 174, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0
  },
  { /* page 2, index 2 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 178, 179, 180, 0, 0, 0, 0, 
    181, 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 3, index 3 */
    357, 358, 359, 360, 361, 0, 362, 363, 364, 365, 366, 367, 368, 0, 0, 369, 
    0, 370, 0, 371, 372, 0, 0, 0, 0, 0, 0, 373, 0, 0, 0, 0, 0, 0, 0, 374, 
    375, 376, 377, 378, 379, 0, 0, 0, 0, 380, 381, 0, 382, 383, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 384, 0, 0, 385, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 
    72, 0, 73, 0, 74, 0, 0, 0, 0, 0, 75, 0, 184, 0, 0, 0, 76, 0, 0, 0, 77, 0, 
    0, 185, 0, 186, 0, 0, 78, 0, 0, 0, 79, 0, 80, 0, 81, 0, 0, 0, 0, 0, 82, 
    0, 83, 0, 0, 0, 84, 0, 0, 0, 85, 86, 87, 0, 0, 187, 0, 0, 0, 88, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 4, index 4 */
    0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 189, 0, 90, 
    91, 190, 92, 0, 191, 0, 0, 0, 192, 0, 0, 0, 0, 93, 0, 0, 0, 193, 0, 0, 0, 
    194, 0, 195, 0, 0, 94, 0, 0, 196, 0, 95, 96, 197, 97, 0, 198, 0, 0, 0, 
    199, 0, 0, 0, 0, 98, 0, 0, 0, 200, 0, 0, 0, 201, 0, 202, 0, 0, 0, 0, 0, 
    0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 207, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 208, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 6, index 5 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    210, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 388, 389, 390, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 
    0, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 9, index 6 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 
    216, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 391, 
    0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    392, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 11, index 7 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 
    101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 394, 395, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 396, 0, 0, 0, 0, 0, 0, 0, 102, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 12, index 8 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 
    0, 0, 398, 0, 0, 0, 103, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 399, 
    400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 13, index 9 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 401, 0, 0, 0, 0, 0, 0, 0, 104, 
    223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 105, 0, 0, 224, 0, 0, 405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 16, index 10 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 30, index 11 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 226, 227, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 229, 0, 0, 
    0, 0, 0, 0, 230, 231, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 233, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 235, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 31, index 12 */
    108, 109, 236, 237, 238, 239, 240, 241, 110, 111, 242, 243, 244, 245, 
    246, 247, 112, 113, 0, 0, 0, 0, 0, 0, 114, 115, 0, 0, 0, 0, 0, 0, 116, 
    117, 248, 249, 250, 251, 252, 253, 118, 119, 254, 255, 256, 257, 258, 
    259, 120, 121, 0, 0, 0, 0, 0, 0, 122, 123, 0, 0, 0, 0, 0, 0, 124, 125, 0, 
    0, 0, 0, 0, 0, 126, 127, 0, 0, 0, 0, 0, 0, 128, 129, 0, 0, 0, 0, 0, 0, 0, 
    130, 0, 0, 0, 0, 0, 0, 131, 132, 260, 261, 262, 263, 264, 265, 133, 134, 
    266, 267, 268, 269, 270, 271, 272, 0, 0, 0, 273, 0, 0, 0, 0, 0, 0, 0, 
    274, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 275, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 
    0, 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 277, 0, 0, 0, 0, 0, 0, 0, 136, 0
  },
  { /* page 33, index 13 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    278, 0, 279, 0, 280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 0, 282, 0, 
    283, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 34, index 14 */
    0, 0, 0, 284, 0, 0, 0, 0, 285, 0, 0, 286, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 287, 0, 288, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 289, 0, 0, 0, 0, 0, 0, 290, 
    0, 291, 0, 0, 292, 0, 0, 0, 0, 293, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 294, 0, 0, 295, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 297, 298, 0, 0, 299, 300, 0, 0, 301, 302, 303, 304, 0, 0, 0, 0, 
    305, 306, 0, 0, 307, 308, 0, 0, 0, 0, 0, 0, 0, 0, 0, 309, 310, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 311, 0, 0, 0, 0, 0, 312, 313, 0, 314, 
    0, 0, 0, 0, 0, 0, 315, 316, 317, 318, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  },
  { /* page 48, index 15 */
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 319, 0, 
    0, 0, 0, 320, 0, 321, 0, 322, 0, 323, 0, 324, 0, 325, 0, 326, 0, 327, 0, 
    328, 0, 329, 0, 330, 0, 331, 0, 0, 332, 0, 333, 0, 334, 0, 0, 0, 0, 0, 0, 
    137, 0, 0, 138, 0, 0, 139, 0, 0, 140, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 386, 387, 
    0, 0, 335, 0, 0, 0, 0, 0, 0, 0, 0, 336, 0, 0, 0, 0, 337, 0, 338, 0, 339, 
    0, 340, 0, 341, 0, 342, 0, 343, 0, 344, 0, 345, 0, 346, 0, 347, 0, 348, 
    0, 0, 349, 0, 350, 0, 351, 0, 0, 0, 0, 0, 0, 142, 0, 0, 143, 0, 0, 144, 
    0, 0, 145, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 352, 353, 354, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 356, 0, 0
  }
};

static const short compose_table[COMPOSE_TABLE_LAST + 1] = {
  0 /* page 0 */,
  1 /* page 1 */,
  2 /* page 2 */,
  3 /* page 3 */,
  4 /* page 4 */,
  0 + UNICODE_MAX_TABLE_INDEX,
  5 /* page 6 */,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  6 /* page 9 */,
  0 + UNICODE_MAX_TABLE_INDEX,
  7 /* page 11 */,
  8 /* page 12 */,
  9 /* page 13 */,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  10 /* page 16 */,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  11 /* page 30 */,
  12 /* page 31 */,
  0 + UNICODE_MAX_TABLE_INDEX,
  13 /* page 33 */,
  14 /* page 34 */,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  0 + UNICODE_MAX_TABLE_INDEX,
  15 /* page 48 */
};

static const unsigned short compose_first_single[][2] = {
 { 0x0338, 0x226e },
 { 0x0338, 0x2260 },
 { 0x0338, 0x226f },
 { 0x0307, 0x1e1e },
 { 0x0302, 0x0134 },
 { 0x0307, 0x1e1f },
 { 0x0304, 0x01de },
 { 0x0301, 0x01fa },
 { 0x0301, 0x1e08 },
 { 0x0301, 0x1e2e },
 { 0x0304, 0x022a },
 { 0x0301, 0x01fe },
 { 0x0304, 0x01df },
 { 0x0301, 0x01fb },
 { 0x0301, 0x1e09 },
 { 0x0301, 0x1e2f },
 { 0x0304, 0x022b },
 { 0x0301, 0x01ff },
 { 0x0307, 0x1e64 },
 { 0x0307, 0x1e65 },
 { 0x0307, 0x1e66 },
 { 0x0307, 0x1e67 },
 { 0x0301, 0x1e78 },
 { 0x0301, 0x1e79 },
 { 0x0308, 0x1e7a },
 { 0x0308, 0x1e7b },
 { 0x0307, 0x1e9b },
 { 0x030c, 0x01ee },
 { 0x0304, 0x01ec },
 { 0x0304, 0x01ed },
 { 0x0304, 0x01e0 },
 { 0x0304, 0x01e1 },
 { 0x0306, 0x1e1c },
 { 0x0306, 0x1e1d },
 { 0x0304, 0x0230 },
 { 0x0304, 0x0231 },
 { 0x030c, 0x01ef },
 { 0x0314, 0x1fec },
 { 0x0345, 0x1fb4 },
 { 0x0345, 0x1fc4 },
 { 0x0345, 0x1ff4 },
 { 0x0308, 0x0407 },
 { 0x0301, 0x0403 },
 { 0x0308, 0x04de },
 { 0x0301, 0x040c },
 { 0x0308, 0x04e6 },
 { 0x0308, 0x04f4 },
 { 0x0308, 0x04f8 },
 { 0x0308, 0x04ec },
 { 0x0301, 0x0453 },
 { 0x0308, 0x04df },
 { 0x0301, 0x045c },
 { 0x0308, 0x04e7 },
 { 0x0308, 0x04f5 },
 { 0x0308, 0x04f9 },
 { 0x0308, 0x04ed },
 { 0x0308, 0x0457 },
 { 0x030f, 0x0476 },
 { 0x030f, 0x0477 },
 { 0x0308, 0x04da },
 { 0x0308, 0x04db },
 { 0x0308, 0x04ea },
 { 0x0308, 0x04eb },
 { 0x0654, 0x0624 },
 { 0x0654, 0x0626 },
 { 0x0654, 0x06c2 },
 { 0x0654, 0x06d3 },
 { 0x0654, 0x06c0 },
 { 0x093c, 0x0929 },
 { 0x093c, 0x0931 },
 { 0x093c, 0x0934 },
 { 0x0bd7, 0x0b94 },
 { 0x0bbe, 0x0bcb },
 { 0x0c56, 0x0c48 },
 { 0x0cd5, 0x0cc0 },
 { 0x0cd5, 0x0ccb },
 { 0x0d3e, 0x0d4b },
 { 0x0dca, 0x0ddd },
 { 0x102e, 0x1026 },
 { 0x0304, 0x1e38 },
 { 0x0304, 0x1e39 },
 { 0x0304, 0x1e5c },
 { 0x0304, 0x1e5d },
 { 0x0307, 0x1e68 },
 { 0x0307, 0x1e69 },
 { 0x0302, 0x1ec6 },
 { 0x0302, 0x1ec7 },
 { 0x0302, 0x1ed8 },
 { 0x0302, 0x1ed9 },
 { 0x0345, 0x1f82 },
 { 0x0345, 0x1f83 },
 { 0x0345, 0x1f84 },
 { 0x0345, 0x1f85 },
 { 0x0345, 0x1f86 },
 { 0x0345, 0x1f87 },
 { 0x0345, 0x1f8a },
 { 0x0345, 0x1f8b },
 { 0x0345, 0x1f8c },
 { 0x0345, 0x1f8d },
 { 0x0345, 0x1f8e },
 { 0x0345, 0x1f8f },
 { 0x0345, 0x1f92 },
 { 0x0345, 0x1f93 },
 { 0x0345, 0x1f94 },
 { 0x0345, 0x1f95 },
 { 0x0345, 0x1f96 },
 { 0x0345, 0x1f97 },
 { 0x0345, 0x1f9a },
 { 0x0345, 0x1f9b },
 { 0x0345, 0x1f9c },
 { 0x0345, 0x1f9d },
 { 0x0345, 0x1f9e },
 { 0x0345, 0x1f9f },
 { 0x0345, 0x1fa2 },
 { 0x0345, 0x1fa3 },
 { 0x0345, 0x1fa4 },
 { 0x0345, 0x1fa5 },
 { 0x0345, 0x1fa6 },
 { 0x0345, 0x1fa7 },
 { 0x0345, 0x1faa },
 { 0x0345, 0x1fab },
 { 0x0345, 0x1fac },
 { 0x0345, 0x1fad },
 { 0x0345, 0x1fae },
 { 0x0345, 0x1faf },
 { 0x0345, 0x1fb2 },
 { 0x0345, 0x1fc2 },
 { 0x0345, 0x1ff2 },
 { 0x0345, 0x1fb7 },
 { 0x0345, 0x1fc7 },
 { 0x0345, 0x1ff7 },
 { 0x0338, 0x219a },
 { 0x0338, 0x219b },
 { 0x0338, 0x21ae },
 { 0x0338, 0x21cd },
 { 0x0338, 0x21cf },
 { 0x0338, 0x21ce },
 { 0x0338, 0x2204 },
 { 0x0338, 0x2209 },
 { 0x0338, 0x220c },
 { 0x0338, 0x2224 },
 { 0x0338, 0x2226 },
 { 0x0338, 0x2241 },
 { 0x0338, 0x2244 },
 { 0x0338, 0x2247 },
 { 0x0338, 0x2249 },
 { 0x0338, 0x226d },
 { 0x0338, 0x2262 },
 { 0x0338, 0x2270 },
 { 0x0338, 0x2271 },
 { 0x0338, 0x2274 },
 { 0x0338, 0x2275 },
 { 0x0338, 0x2278 },
 { 0x0338, 0x2279 },
 { 0x0338, 0x2280 },
 { 0x0338, 0x2281 },
 { 0x0338, 0x22e0 },
 { 0x0338, 0x22e1 },
 { 0x0338, 0x2284 },
 { 0x0338, 0x2285 },
 { 0x0338, 0x2288 },
 { 0x0338, 0x2289 },
 { 0x0338, 0x22e2 },
 { 0x0338, 0x22e3 },
 { 0x0338, 0x22ac },
 { 0x0338, 0x22ad },
 { 0x0338, 0x22ae },
 { 0x0338, 0x22af },
 { 0x0338, 0x22ea },
 { 0x0338, 0x22eb },
 { 0x0338, 0x22ec },
 { 0x0338, 0x22ed },
 { 0x3099, 0x3094 },
 { 0x3099, 0x304c },
 { 0x3099, 0x304e },
 { 0x3099, 0x3050 },
 { 0x3099, 0x3052 },
 { 0x3099, 0x3054 },
 { 0x3099, 0x3056 },
 { 0x3099, 0x3058 },
 { 0x3099, 0x305a },
 { 0x3099, 0x305c },
 { 0x3099, 0x305e },
 { 0x3099, 0x3060 },
 { 0x3099, 0x3062 },
 { 0x3099, 0x3065 },
 { 0x3099, 0x3067 },
 { 0x3099, 0x3069 },
 { 0x3099, 0x309e },
 { 0x3099, 0x30f4 },
 { 0x3099, 0x30ac },
 { 0x3099, 0x30ae },
 { 0x3099, 0x30b0 },
 { 0x3099, 0x30b2 },
 { 0x3099, 0x30b4 },
 { 0x3099, 0x30b6 },
 { 0x3099, 0x30b8 },
 { 0x3099, 0x30ba },
 { 0x3099, 0x30bc },
 { 0x3099, 0x30be },
 { 0x3099, 0x30c0 },
 { 0x3099, 0x30c2 },
 { 0x3099, 0x30c5 },
 { 0x3099, 0x30c7 },
 { 0x3099, 0x30c9 },
 { 0x3099, 0x30f7 },
 { 0x3099, 0x30f8 },
 { 0x3099, 0x30f9 },
 { 0x3099, 0x30fa },
 { 0x3099, 0x30fe }
};
static const unsigned short compose_second_single[][2] = {
 { 0x0627, 0x0622 },
 { 0x0627, 0x0623 },
 { 0x0627, 0x0625 },
 { 0x09c7, 0x09cb },
 { 0x09c7, 0x09cc },
 { 0x0b47, 0x0b4b },
 { 0x0b47, 0x0b48 },
 { 0x0b47, 0x0b4c },
 { 0x0bc6, 0x0bca },
 { 0x0bc6, 0x0bcc },
 { 0x0cc6, 0x0cca },
 { 0x0cc6, 0x0cc7 },
 { 0x0cc6, 0x0cc8 },
 { 0x0d46, 0x0d4a },
 { 0x0d46, 0x0d4c },
 { 0x0dd9, 0x0dda },
 { 0x0dd9, 0x0ddc },
 { 0x0dd9, 0x0dde }
};
static const unsigned short compose_array[146][31] = {
 { 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x0100, 0x0102, 0x0226, 0x00c4, 0x1ea2, 0x00c5,      0, 0x01cd, 0x0200, 0x0202,      0,      0,      0, 0x1ea0,      0, 0x1e00,      0,      0, 0x0104,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0, 0x1e02,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e04,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e06,      0,      0,      0,      0 },
 {      0, 0x0106, 0x0108,      0,      0,      0, 0x010a,      0,      0,      0,      0, 0x010c,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x00c7,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0, 0x1e0a,      0,      0,      0,      0, 0x010e,      0,      0,      0,      0,      0, 0x1e0c,      0,      0,      0, 0x1e10,      0, 0x1e12,      0,      0, 0x1e0e,      0,      0,      0,      0 },
 { 0x00c8, 0x00c9, 0x00ca, 0x1ebc, 0x0112, 0x0114, 0x0116, 0x00cb, 0x1eba,      0,      0, 0x011a, 0x0204, 0x0206,      0,      0,      0, 0x1eb8,      0,      0,      0, 0x0228, 0x0118, 0x1e18,      0, 0x1e1a,      0,      0,      0,      0,      0 },
 {      0, 0x01f4, 0x011c,      0, 0x1e20, 0x011e, 0x0120,      0,      0,      0,      0, 0x01e6,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x0122,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0, 0x0124,      0,      0,      0, 0x1e22, 0x1e26,      0,      0,      0, 0x021e,      0,      0,      0,      0,      0, 0x1e24,      0,      0,      0, 0x1e28,      0,      0, 0x1e2a,      0,      0,      0,      0,      0,      0 },
 { 0x00cc, 0x00cd, 0x00ce, 0x0128, 0x012a, 0x012c, 0x0130, 0x00cf, 0x1ec8,      0,      0, 0x01cf, 0x0208, 0x020a,      0,      0,      0, 0x1eca,      0,      0,      0,      0, 0x012e,      0,      0, 0x1e2c,      0,      0,      0,      0,      0 },
 {      0, 0x1e30,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x01e8,      0,      0,      0,      0,      0, 0x1e32,      0,      0,      0, 0x0136,      0,      0,      0,      0, 0x1e34,      0,      0,      0,      0 },
 {      0, 0x0139,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x013d,      0,      0,      0,      0,      0, 0x1e36,      0,      0,      0, 0x013b,      0, 0x1e3c,      0,      0, 0x1e3a,      0,      0,      0,      0 },
 {      0, 0x1e3e,      0,      0,      0,      0, 0x1e40,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e42,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x01f8, 0x0143,      0, 0x00d1,      0,      0, 0x1e44,      0,      0,      0,      0, 0x0147,      0,      0,      0,      0,      0, 0x1e46,      0,      0,      0, 0x0145,      0, 0x1e4a,      0,      0, 0x1e48,      0,      0,      0,      0 },
 { 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x014c, 0x014e, 0x022e, 0x00d6, 0x1ece,      0, 0x0150, 0x01d1, 0x020c, 0x020e,      0,      0, 0x01a0, 0x1ecc,      0,      0,      0,      0, 0x01ea,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x1e54,      0,      0,      0,      0, 0x1e56,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x0154,      0,      0,      0,      0, 0x1e58,      0,      0,      0,      0, 0x0158, 0x0210, 0x0212,      0,      0,      0, 0x1e5a,      0,      0,      0, 0x0156,      0,      0,      0,      0, 0x1e5e,      0,      0,      0,      0 },
 {      0, 0x015a, 0x015c,      0,      0,      0, 0x1e60,      0,      0,      0,      0, 0x0160,      0,      0,      0,      0,      0, 0x1e62,      0,      0, 0x0218, 0x015e,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0, 0x1e6a,      0,      0,      0,      0, 0x0164,      0,      0,      0,      0,      0, 0x1e6c,      0,      0, 0x021a, 0x0162,      0, 0x1e70,      0,      0, 0x1e6e,      0,      0,      0,      0 },
 { 0x00d9, 0x00da, 0x00db, 0x0168, 0x016a, 0x016c,      0, 0x00dc, 0x1ee6, 0x016e, 0x0170, 0x01d3, 0x0214, 0x0216,      0,      0, 0x01af, 0x1ee4, 0x1e72,      0,      0,      0, 0x0172, 0x1e76,      0, 0x1e74,      0,      0,      0,      0,      0 },
 {      0,      0,      0, 0x1e7c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e7e,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1e80, 0x1e82, 0x0174,      0,      0,      0, 0x1e86, 0x1e84,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e88,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0, 0x1e8a, 0x1e8c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ef2, 0x00dd, 0x0176, 0x1ef8, 0x0232,      0, 0x1e8e, 0x0178, 0x1ef6,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ef4,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x0179, 0x1e90,      0,      0,      0, 0x017b,      0,      0,      0,      0, 0x017d,      0,      0,      0,      0,      0, 0x1e92,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e94,      0,      0,      0,      0 },
 { 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x0101, 0x0103, 0x0227, 0x00e4, 0x1ea3, 0x00e5,      0, 0x01ce, 0x0201, 0x0203,      0,      0,      0, 0x1ea1,      0, 0x1e01,      0,      0, 0x0105,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0, 0x1e03,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e05,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e07,      0,      0,      0,      0 },
 {      0, 0x0107, 0x0109,      0,      0,      0, 0x010b,      0,      0,      0,      0, 0x010d,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x00e7,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0, 0x1e0b,      0,      0,      0,      0, 0x010f,      0,      0,      0,      0,      0, 0x1e0d,      0,      0,      0, 0x1e11,      0, 0x1e13,      0,      0, 0x1e0f,      0,      0,      0,      0 },
 { 0x00e8, 0x00e9, 0x00ea, 0x1ebd, 0x0113, 0x0115, 0x0117, 0x00eb, 0x1ebb,      0,      0, 0x011b, 0x0205, 0x0207,      0,      0,      0, 0x1eb9,      0,      0,      0, 0x0229, 0x0119, 0x1e19,      0, 0x1e1b,      0,      0,      0,      0,      0 },
 {      0, 0x01f5, 0x011d,      0, 0x1e21, 0x011f, 0x0121,      0,      0,      0,      0, 0x01e7,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x0123,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0, 0x0125,      0,      0,      0, 0x1e23, 0x1e27,      0,      0,      0, 0x021f,      0,      0,      0,      0,      0, 0x1e25,      0,      0,      0, 0x1e29,      0,      0, 0x1e2b,      0, 0x1e96,      0,      0,      0,      0 },
 { 0x00ec, 0x00ed, 0x00ee, 0x0129, 0x012b, 0x012d,      0, 0x00ef, 0x1ec9,      0,      0, 0x01d0, 0x0209, 0x020b,      0,      0,      0, 0x1ecb,      0,      0,      0,      0, 0x012f,      0,      0, 0x1e2d,      0,      0,      0,      0,      0 },
 {      0,      0, 0x0135,      0,      0,      0,      0,      0,      0,      0,      0, 0x01f0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x1e31,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x01e9,      0,      0,      0,      0,      0, 0x1e33,      0,      0,      0, 0x0137,      0,      0,      0,      0, 0x1e35,      0,      0,      0,      0 },
 {      0, 0x013a,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x013e,      0,      0,      0,      0,      0, 0x1e37,      0,      0,      0, 0x013c,      0, 0x1e3d,      0,      0, 0x1e3b,      0,      0,      0,      0 },
 {      0, 0x1e3f,      0,      0,      0,      0, 0x1e41,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e43,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x01f9, 0x0144,      0, 0x00f1,      0,      0, 0x1e45,      0,      0,      0,      0, 0x0148,      0,      0,      0,      0,      0, 0x1e47,      0,      0,      0, 0x0146,      0, 0x1e4b,      0,      0, 0x1e49,      0,      0,      0,      0 },
 { 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x014d, 0x014f, 0x022f, 0x00f6, 0x1ecf,      0, 0x0151, 0x01d2, 0x020d, 0x020f,      0,      0, 0x01a1, 0x1ecd,      0,      0,      0,      0, 0x01eb,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x1e55,      0,      0,      0,      0, 0x1e57,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x0155,      0,      0,      0,      0, 0x1e59,      0,      0,      0,      0, 0x0159, 0x0211, 0x0213,      0,      0,      0, 0x1e5b,      0,      0,      0, 0x0157,      0,      0,      0,      0, 0x1e5f,      0,      0,      0,      0 },
 {      0, 0x015b, 0x015d,      0,      0,      0, 0x1e61,      0,      0,      0,      0, 0x0161,      0,      0,      0,      0,      0, 0x1e63,      0,      0, 0x0219, 0x015f,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0, 0x1e6b, 0x1e97,      0,      0,      0, 0x0165,      0,      0,      0,      0,      0, 0x1e6d,      0,      0, 0x021b, 0x0163,      0, 0x1e71,      0,      0, 0x1e6f,      0,      0,      0,      0 },
 { 0x00f9, 0x00fa, 0x00fb, 0x0169, 0x016b, 0x016d,      0, 0x00fc, 0x1ee7, 0x016f, 0x0171, 0x01d4, 0x0215, 0x0217,      0,      0, 0x01b0, 0x1ee5, 0x1e73,      0,      0,      0, 0x0173, 0x1e77,      0, 0x1e75,      0,      0,      0,      0,      0 },
 {      0,      0,      0, 0x1e7d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e7f,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1e81, 0x1e83, 0x0175,      0,      0,      0, 0x1e87, 0x1e85,      0, 0x1e98,      0,      0,      0,      0,      0,      0,      0, 0x1e89,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0, 0x1e8b, 0x1e8d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ef3, 0x00fd, 0x0177, 0x1ef9, 0x0233,      0, 0x1e8f, 0x00ff, 0x1ef7, 0x1e99,      0,      0,      0,      0,      0,      0,      0, 0x1ef5,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x017a, 0x1e91,      0,      0,      0, 0x017c,      0,      0,      0,      0, 0x017e,      0,      0,      0,      0,      0, 0x1e93,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e95,      0,      0,      0,      0 },
 { 0x1fed, 0x0385,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fc1,      0,      0,      0 },
 { 0x1ea6, 0x1ea4,      0, 0x1eaa,      0,      0,      0,      0, 0x1ea8,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x01fc,      0,      0, 0x01e2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ec0, 0x1ebe,      0, 0x1ec4,      0,      0,      0,      0, 0x1ec2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ed2, 0x1ed0,      0, 0x1ed6,      0,      0,      0,      0, 0x1ed4,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x1e4c,      0,      0, 0x022c,      0,      0, 0x1e4e,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x01db, 0x01d7,      0,      0, 0x01d5,      0,      0,      0,      0,      0,      0, 0x01d9,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ea7, 0x1ea5,      0, 0x1eab,      0,      0,      0,      0, 0x1ea9,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x01fd,      0,      0, 0x01e3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ec1, 0x1ebf,      0, 0x1ec5,      0,      0,      0,      0, 0x1ec3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ed3, 0x1ed1,      0, 0x1ed7,      0,      0,      0,      0, 0x1ed5,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0, 0x1e4d,      0,      0, 0x022d,      0,      0, 0x1e4f,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x01dc, 0x01d8,      0,      0, 0x01d6,      0,      0,      0,      0,      0,      0, 0x01da,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1eb0, 0x1eae,      0, 0x1eb4,      0,      0,      0,      0, 0x1eb2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1eb1, 0x1eaf,      0, 0x1eb5,      0,      0,      0,      0, 0x1eb3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1e14, 0x1e16,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1e15, 0x1e17,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1e50, 0x1e52,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1e51, 0x1e53,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1edc, 0x1eda,      0, 0x1ee0,      0,      0,      0,      0, 0x1ede,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ee2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1edd, 0x1edb,      0, 0x1ee1,      0,      0,      0,      0, 0x1edf,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ee3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1eea, 0x1ee8,      0, 0x1eee,      0,      0,      0,      0, 0x1eec,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ef0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1eeb, 0x1ee9,      0, 0x1eef,      0,      0,      0,      0, 0x1eed,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ef1,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1fba, 0x0386,      0,      0, 0x1fb9, 0x1fb8,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f08, 0x1f09,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fbc,      0,      0 },
 { 0x1fc8, 0x0388,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f18, 0x1f19,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1fca, 0x0389,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f28, 0x1f29,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fcc,      0,      0 },
 { 0x1fda, 0x038a,      0,      0, 0x1fd9, 0x1fd8,      0, 0x03aa,      0,      0,      0,      0,      0,      0, 0x1f38, 0x1f39,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ff8, 0x038c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f48, 0x1f49,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1fea, 0x038e,      0,      0, 0x1fe9, 0x1fe8,      0, 0x03ab,      0,      0,      0,      0,      0,      0,      0, 0x1f59,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1ffa, 0x038f,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f68, 0x1f69,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ffc,      0,      0 },
 { 0x1f70, 0x03ac,      0,      0, 0x1fb1, 0x1fb0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f00, 0x1f01,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fb6, 0x1fb3,      0,      0 },
 { 0x1f72, 0x03ad,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f10, 0x1f11,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f74, 0x03ae,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f20, 0x1f21,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fc6, 0x1fc3,      0,      0 },
 { 0x1f76, 0x03af,      0,      0, 0x1fd1, 0x1fd0,      0, 0x03ca,      0,      0,      0,      0,      0,      0, 0x1f30, 0x1f31,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fd6,      0,      0,      0 },
 { 0x1f78, 0x03cc,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f40, 0x1f41,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fe4, 0x1fe5,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f7a, 0x03cd,      0,      0, 0x1fe1, 0x1fe0,      0, 0x03cb,      0,      0,      0,      0,      0,      0, 0x1f50, 0x1f51,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fe6,      0,      0,      0 },
 { 0x1f7c, 0x03ce,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f60, 0x1f61,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ff6, 0x1ff3,      0,      0 },
 { 0x1fd2, 0x0390,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fd7,      0,      0,      0 },
 { 0x1fe2, 0x03b0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fe7,      0,      0,      0 },
 {      0, 0x03d3,      0,      0,      0,      0,      0, 0x03d4,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0, 0x04d0,      0, 0x04d2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x0400,      0,      0,      0,      0, 0x04d6,      0, 0x0401,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0, 0x04c1,      0, 0x04dc,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x040d,      0,      0,      0, 0x04e2, 0x0419,      0, 0x04e4,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0, 0x04ee, 0x040e,      0, 0x04f0,      0,      0, 0x04f2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0, 0x04d1,      0, 0x04d3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x0450,      0,      0,      0,      0, 0x04d7,      0, 0x0451,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0, 0x04c2,      0, 0x04dd,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x045d,      0,      0,      0, 0x04e3, 0x0439,      0, 0x04e5,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0, 0x04ef, 0x045e,      0, 0x04f1,      0,      0, 0x04f3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0, 0x1eac,      0,      0, 0x1eb6,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 {      0,      0, 0x1ead,      0,      0, 0x1eb7,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f02, 0x1f04,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f06, 0x1f80,      0,      0 },
 { 0x1f03, 0x1f05,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f07, 0x1f81,      0,      0 },
 { 0x1f0a, 0x1f0c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f0e, 0x1f88,      0,      0 },
 { 0x1f0b, 0x1f0d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f0f, 0x1f89,      0,      0 },
 { 0x1f12, 0x1f14,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f13, 0x1f15,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f1a, 0x1f1c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f1b, 0x1f1d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f22, 0x1f24,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f26, 0x1f90,      0,      0 },
 { 0x1f23, 0x1f25,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f27, 0x1f91,      0,      0 },
 { 0x1f2a, 0x1f2c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f2e, 0x1f98,      0,      0 },
 { 0x1f2b, 0x1f2d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f2f, 0x1f99,      0,      0 },
 { 0x1f32, 0x1f34,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f36,      0,      0,      0 },
 { 0x1f33, 0x1f35,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f37,      0,      0,      0 },
 { 0x1f3a, 0x1f3c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f3e,      0,      0,      0 },
 { 0x1f3b, 0x1f3d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f3f,      0,      0,      0 },
 { 0x1f42, 0x1f44,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f43, 0x1f45,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f4a, 0x1f4c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f4b, 0x1f4d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
 { 0x1f52, 0x1f54,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f56,      0,      0,      0 },
 { 0x1f53, 0x1f55,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f57,      0,      0,      0 },
 { 0x1f5b, 0x1f5d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f5f,      0,      0,      0 },
 { 0x1f62, 0x1f64,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f66, 0x1fa0,      0,      0 },
 { 0x1f63, 0x1f65,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f67, 0x1fa1,      0,      0 },
 { 0x1f6a, 0x1f6c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f6e, 0x1fa8,      0,      0 },
 { 0x1f6b, 0x1f6d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f6f, 0x1fa9,      0,      0 },
 { 0x1fcd, 0x1fce,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fcf,      0,      0,      0 },
 { 0x1fdd, 0x1fde,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fdf,      0,      0,      0 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x3070, 0x3071 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x3073, 0x3074 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x3076, 0x3077 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x3079, 0x307a },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x307c, 0x307d },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30d0, 0x30d1 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30d3, 0x30d4 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30d6, 0x30d7 },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30d9, 0x30da },
 {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30dc, 0x30dd }
};

--- NEW FILE: UnicodeDecompTables.h ---
// Generated by gen-unicode-tables.py

typedef struct {
  Unicode character;
  int length;
  int offset;
} decomposition;

#define DECOMP_TABLE_LENGTH 5143

static const decomposition decomp_table[] = {
  { 0xa0, 1, 0 }, 
  { 0xa8, 2, 1 }, 
  { 0xaa, 1, 3 }, 
  { 0xaf, 2, 4 }, 
  { 0xb2, 1, 6 }, 
  { 0xb3, 1, 7 }, 
  { 0xb4, 2, 8 }, 
  { 0xb5, 1, 10 }, 
[...8487 lines suppressed...]
  0x29b30 /* offset 6137 */ , 
  0x9b12 /* offset 6138 */ , 
  0x9c40 /* offset 6139 */ , 
  0x9cfd /* offset 6140 */ , 
  0x4cce /* offset 6141 */ , 
  0x4ced /* offset 6142 */ , 
  0x9d67 /* offset 6143 */ , 
  0x2a0ce /* offset 6144 */ , 
  0x4cf8 /* offset 6145 */ , 
  0x2a105 /* offset 6146 */ , 
  0x2a20e /* offset 6147 */ , 
  0x2a291 /* offset 6148 */ , 
  0x4d56 /* offset 6149 */ , 
  0x9efe /* offset 6150 */ , 
  0x9f05 /* offset 6151 */ , 
  0x9f0f /* offset 6152 */ , 
  0x9f16 /* offset 6153 */ , 
  0x2a600 /* offset 6154 */ 
};


Index: UnicodeTypeTable.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/UnicodeTypeTable.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- UnicodeTypeTable.cc	20 Sep 2005 14:43:15 -0000	1.3
+++ UnicodeTypeTable.cc	19 May 2006 22:04:17 -0000	1.4
@@ -9,6 +9,7 @@
 #include <stdlib.h>
 #include "CharTypes.h"
 #include "UnicodeTypeTable.h"
+#include "goo/gmem.h"
 
 struct UnicodeMapTableEntry {
   char *vector;
@@ -947,3 +948,237 @@
   return c;
 }
 
+#define UNICODE_LAST_CHAR 0x10FFFF
+#define UNICODE_MAX_TABLE_INDEX (UNICODE_LAST_CHAR / 256 + 1)
+// large empty block between U+2FA1D and U+E0001
+#define UNICODE_LAST_CHAR_PART1 0x2FAFF
+#define UNICODE_LAST_PAGE_PART1 (UNICODE_LAST_CHAR_PART1 / 256)
+#define UNICODE_PART2_START 0xE0000
+
+#include "UnicodeCClassTables.h"
+#include "UnicodeCompTables.h"
+#include "UnicodeDecompTables.h"
+
+#define CC_PART1(Page, Char) \
+  ((combining_class_table_part1[Page] >= UNICODE_MAX_TABLE_INDEX) \
+   ? (combining_class_table_part1[Page] - UNICODE_MAX_TABLE_INDEX) \
+   : (cclass_data[combining_class_table_part1[Page]][Char]))
+
+#define CC_PART2(Page, Char) \
+  ((combining_class_table_part2[Page] >= UNICODE_MAX_TABLE_INDEX) \
+   ? (combining_class_table_part2[Page] - UNICODE_MAX_TABLE_INDEX) \
+   : (cclass_data[combining_class_table_part2[Page]][Char]))
+
+#define COMBINING_CLASS(u) (((u) <= UNICODE_LAST_CHAR_PART1) \
+    ? CC_PART1((u) / 256, (u) % 256) \
+    : (((u) >= UNICODE_PART2_START && (u) <= UNICODE_LAST_CHAR) \
+      ? CC_PART2(((u) - UNICODE_PART2_START) / 256, (u) % 256) \
+      : 0))
+
+// Write the compatibility decomposition of @u into @buf, returning the number 
+// of characters written. @buf may be NULL, in which case the length of the
+// decomposition is returned but nothing is written. If @u is its own
+// decomposition, write @u into @buf and return 1.
+static int decomp_compat(Unicode u, Unicode *buf) {
+  // decomposition tables stored as lists {character, decomp_length, offset}
+  // so we do a binary search
+  int start = 0, end = DECOMP_TABLE_LENGTH;
+  if (u >= decomp_table[start].character 
+      && u <= decomp_table[end - 1].character)
+    while (gTrue) {
+      int midpoint = (start + end) / 2;
+      if (u == decomp_table[midpoint].character) {
+	int offset = decomp_table[midpoint].offset;
+	if (offset == -1)
+	  break;
+	else {
+	  int length = decomp_table[midpoint].length, i;
+	  if (buf)
+	    for (i = 0; i < length; ++i)
+	      buf[i] = decomp_expansion[offset + i];
+	  return length;
+	}
+      } else if (midpoint == start)
+	break;
+      else if (u > decomp_table[midpoint].character)
+	start = midpoint;
+      else
+	end = midpoint;
+    }
+  if (buf)
+    *buf = u;
+  return 1;
+}
+
+#define CI(Page, Char) \
+  ((compose_table[Page] >= UNICODE_MAX_TABLE_INDEX) \
+   ? (compose_table[Page] - UNICODE_MAX_TABLE_INDEX) \
+   : (compose_data[compose_table[Page]][Char]))
+
+#define COMPOSE_INDEX(u) \
+     ((((u) / 256) > (COMPOSE_TABLE_LAST)) ? 0 : CI((u) / 256, (u) % 255))
+
+// If @add combines with @base, write the combination to @out and return 
+// gTrue. Otherwise return gFalse.
+static GBool combine(Unicode base, Unicode add, Unicode *out) {
+  unsigned short idx_base, idx_add;
+
+  idx_base = COMPOSE_INDEX(base);
+  if (idx_base >= COMPOSE_FIRST_SINGLE_START 
+      && idx_base < COMPOSE_SECOND_START) {
+    if (compose_first_single[idx_base - COMPOSE_FIRST_SINGLE_START][0]
+	== add) {
+      *out = compose_first_single[idx_base - COMPOSE_FIRST_SINGLE_START][1];
+      return gTrue;
+    } else
+      return gFalse;
+  }
+
+  idx_add = COMPOSE_INDEX(add);
+  if (idx_add >= COMPOSE_SECOND_SINGLE_START) {
+    if (compose_second_single[idx_add - COMPOSE_SECOND_SINGLE_START][0]
+	== base) {
+      *out = compose_second_single[idx_add - COMPOSE_SECOND_SINGLE_START][1];
+      return gTrue;
+    } else
+      return gFalse;
+  }
+
+  if (idx_base >= COMPOSE_FIRST_START && idx_base < COMPOSE_FIRST_SINGLE_START 
+      && idx_add >= COMPOSE_SECOND_START 
+      && idx_add < COMPOSE_SECOND_SINGLE_START) {
+    Unicode o = compose_array[idx_base - COMPOSE_FIRST_START]
+      [idx_add - COMPOSE_SECOND_START];
+    if (o) {
+      *out = o;
+      return gTrue;
+    }
+  }
+
+  return gFalse;
+}
+
+#define HANGUL_S_BASE 0xAC00
+#define HANGUL_L_BASE 0x1100
+#define HANGUL_V_BASE 0x1161
+#define HANGUL_T_BASE 0x11A7
+#define HANGUL_L_COUNT 19
+#define HANGUL_V_COUNT 21
+#define HANGUL_T_COUNT 28
+#define HANGUL_S_COUNT (HANGUL_L_COUNT * HANGUL_V_COUNT * HANGUL_T_COUNT)
+#define HANGUL_N_COUNT (HANGUL_V_COUNT * HANGUL_T_COUNT)
+#define HANGUL_IS_L(u) (((u) >= HANGUL_L_BASE) \
+    && ((u) < HANGUL_L_BASE + HANGUL_L_COUNT))
+#define HANGUL_IS_V(u) (((u) >= HANGUL_V_BASE) \
+    && ((u) < HANGUL_V_BASE + HANGUL_V_COUNT))
+#define HANGUL_IS_T(u) (((u) >= HANGUL_T_BASE) \
+    && ((u) < HANGUL_T_BASE + HANGUL_T_COUNT))
+#define HANGUL_IS_SYLLABLE(u) (((u) >= HANGUL_S_BASE) \
+    && ((u) < HANGUL_S_BASE + HANGUL_S_COUNT))
+#define HANGUL_SYLLABLE_IS_LV(u) (((u) - HANGUL_S_BASE) % HANGUL_T_COUNT == 0)
+#define IS_HANGUL(u) (HANGUL_IS_L(u) || HANGUL_IS_V(u) || HANGUL_IS_T(u) \
+    || HANGUL_IS_SYLLABLE(u))
+#define HANGUL_COMPOSE_L_V(l, v) (HANGUL_S_BASE + (HANGUL_T_COUNT * \
+      (((v) - HANGUL_V_BASE) + (HANGUL_V_COUNT * ((l) - HANGUL_L_BASE)))))
+#define HANGUL_COMPOSE_LV_T(lv, t) ((lv) + ((t) - HANGUL_T_BASE))
+
+// Converts Unicode string @in of length @len to its normalization in form 
+// NFKC (compatibility decomposition + canonical composition). The length of
+// the resulting Unicode string is returned in @out_len. If non-NULL, @indices
+// is assigned the location of a newly-allocated array of length @out_len + 1, 
+// for each character in the normalized string giving the index in @in of the 
+// corresponding unnormalized character. @indices is not guaranteed monotone or
+// onto.
+Unicode *unicodeNormalizeNFKC(Unicode *in, int len, 
+			      int *out_len, int **indices) {
+  Unicode *out;
+  int i, o, *classes, *idx = NULL;
+
+  for (i = 0, o = 0; i < len; ++i) {
+    if (HANGUL_IS_L(in[i]) || HANGUL_IS_SYLLABLE(in[i])) {
+      o += 1;
+    } else
+      o += decomp_compat(in[i], NULL);
+  }
+  
+  out = (Unicode *) gmallocn(o, sizeof(Unicode));
+  classes = (int *) gmallocn(o, sizeof(int));
+  if (indices)
+    idx = (int *) gmallocn(o + 1, sizeof(int));
+
+  for (i = 0, o = 0; i < len; ) {
+    Unicode u = in[i];
+    if (IS_HANGUL(u)) {
+      if (HANGUL_IS_L(u)) {
+	Unicode l = u;
+	if (i+1 < len && HANGUL_IS_V(in[i+1])) {
+	  Unicode lv = HANGUL_COMPOSE_L_V(l, in[++i]);
+	  if (i+1 < len && HANGUL_IS_T(in[i+1]))
+	    out[o] = HANGUL_COMPOSE_LV_T(lv, in[++i]);
+	  else
+	    out[o] = lv;
+	} else
+	  out[o] = l;
+      } else if (HANGUL_SYLLABLE_IS_LV(u)) {
+	Unicode lv = u;
+	if (i+1 < len && HANGUL_IS_T(in[i+1]))
+	  out[o] = HANGUL_COMPOSE_LV_T(lv, in[++i]);
+	else
+	  out[o] = lv;
+      } else
+	out[o] = u;
+      if (indices)
+	idx[o] = i;
+      ++i; ++o;
+    } else {
+      int j, p, q, r, s, dlen;
+      // write compatibility decompositions into out (we have enough space)
+      // chomp in until a starter is reached
+      for (j = i, p = o; j < len; ++j) {
+	u = in[j];
+	if (j != i && COMBINING_CLASS(u) == 0)
+	  break;
+	dlen = decomp_compat(u, out + p);
+	for (q = p; q < p + dlen; ++q) {
+	  classes[q] = COMBINING_CLASS(out[q]);
+	  if (indices)
+	    idx[q] = j;
+	}
+	p += dlen;
+      }
+      // put out[o, p) in canonical ordering
+      for (q = o + 1; q < p; ++q)
+	for (r = q; r > o + 1; --r) { 	// FIXME worth using a better sort?
+	  int swap;
+	  if (classes[r] >= classes[r-1])
+	    break;
+	  u = out[r]; out[r] = out[r - 1]; out[r - 1] = u;
+	  swap = classes[r]; classes[r] = classes[r - 1]; classes[r - 1] = swap;
+	  if (indices)
+	    swap = idx[r]; idx[r] = idx[r - 1]; idx[r - 1] = swap;
+	}
+      // canonical compose out[o, p)
+      for (q = o + 1; q < p; ++q)
+	if (!combine(out[o], out[q], &out[o]))
+	  break;
+      // move out[q, p) back to [o+1, ?)
+      if (q != o + 1)
+	for (r = q, s = o + 1; r < p; ++r, ++s) {
+	  out[s] = out[r];
+	  if (indices)
+	    idx[s] = idx[r];
+	}
+      else
+	s = p;
+      i = j; o = s;
+    }
+  }
+
+  *out_len = o;
+  gfree(classes);
+  if (indices) {
+    idx[o] = len;
+    *indices = idx;
+  }
+  return out;
+}

Index: UnicodeTypeTable.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/UnicodeTypeTable.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- UnicodeTypeTable.h	16 Sep 2005 18:35:29 -0000	1.2
+++ UnicodeTypeTable.h	19 May 2006 22:04:17 -0000	1.3
@@ -17,4 +17,7 @@
 
 extern Unicode unicodeToUpper(Unicode c);
 
+extern Unicode *unicodeNormalizeNFKC(Unicode *in, int len, 
+				     int *out_len, int **offsets);
+
 #endif



More information about the poppler mailing list