diff options
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r-- | drivers/tty/vt/.gitignore | 3 | ||||
-rw-r--r-- | drivers/tty/vt/Makefile | 34 | ||||
-rw-r--r-- | drivers/tty/vt/consolemap.c | 2 | ||||
-rwxr-xr-x | drivers/tty/vt/gen_ucs_fallback_table.py | 360 | ||||
-rwxr-xr-x | drivers/tty/vt/gen_ucs_recompose_table.py | 257 | ||||
-rwxr-xr-x | drivers/tty/vt/gen_ucs_width_table.py | 307 | ||||
-rw-r--r-- | drivers/tty/vt/keyboard.c | 37 | ||||
-rw-r--r-- | drivers/tty/vt/selection.c | 31 | ||||
-rw-r--r-- | drivers/tty/vt/ucs.c | 251 | ||||
-rw-r--r-- | drivers/tty/vt/ucs_fallback_table.h_shipped | 3346 | ||||
-rw-r--r-- | drivers/tty/vt/ucs_recompose_table.h_shipped | 102 | ||||
-rw-r--r-- | drivers/tty/vt/ucs_width_table.h_shipped | 453 | ||||
-rw-r--r-- | drivers/tty/vt/vt.c | 244 | ||||
-rw-r--r-- | drivers/tty/vt/vt_ioctl.c | 18 |
14 files changed, 5333 insertions, 112 deletions
diff --git a/drivers/tty/vt/.gitignore b/drivers/tty/vt/.gitignore index 0221709b177d..a74859bab862 100644 --- a/drivers/tty/vt/.gitignore +++ b/drivers/tty/vt/.gitignore @@ -2,3 +2,6 @@ /conmakehash /consolemap_deftbl.c /defkeymap.c +/ucs_fallback_table.h +/ucs_recompose_table.h +/ucs_width_table.h diff --git a/drivers/tty/vt/Makefile b/drivers/tty/vt/Makefile index 2c8ce8b592ed..ae746dcdeec8 100644 --- a/drivers/tty/vt/Makefile +++ b/drivers/tty/vt/Makefile @@ -7,10 +7,12 @@ FONTMAPFILE = cp437.uni obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o \ selection.o keyboard.o \ vt.o defkeymap.o -obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o +obj-$(CONFIG_CONSOLE_TRANSLATIONS) += consolemap.o consolemap_deftbl.o \ + ucs.o # Files generated that shall be removed upon make clean -clean-files := consolemap_deftbl.c defkeymap.c +clean-files := consolemap_deftbl.c defkeymap.c \ + ucs_width_table.h ucs_recompose_table.h ucs_fallback_table.h hostprogs += conmakehash @@ -33,3 +35,31 @@ $(obj)/defkeymap.c: $(obj)/%.c: $(src)/%.map loadkeys --mktable --unicode $< > $@ endif + +$(obj)/ucs.o: $(src)/ucs.c $(obj)/ucs_width_table.h \ + $(obj)/ucs_recompose_table.h $(obj)/ucs_fallback_table.h + +# You may uncomment one of those to have the UCS tables be regenerated +# during the build process. By default the _shipped versions are used. +# +#GENERATE_UCS_TABLES := 1 +#GENERATE_UCS_TABLES := 2 # invokes gen_ucs_recompose_table.py with --full + +ifdef GENERATE_UCS_TABLES + +$(obj)/ucs_width_table.h: $(src)/gen_ucs_width_table.py + $(PYTHON3) $< -o $@ + +ifeq ($(GENERATE_UCS_TABLES),2) +gen_recomp_arg := --full +else +gen_recomp_arg := +endif + +$(obj)/ucs_recompose_table.h: $(src)/gen_ucs_recompose_table.py + $(PYTHON3) $< -o $@ $(gen_recomp_arg) + +$(obj)/ucs_fallback_table.h: $(src)/gen_ucs_fallback_table.py + $(PYTHON3) $< -o $@ + +endif diff --git a/drivers/tty/vt/consolemap.c b/drivers/tty/vt/consolemap.c index 82d70083fead..bb4bb272ebec 100644 --- a/drivers/tty/vt/consolemap.c +++ b/drivers/tty/vt/consolemap.c @@ -870,8 +870,6 @@ int conv_uni_to_pc(struct vc_data *conp, long ucs) return -4; /* Not found */ else if (ucs < 0x20) return -1; /* Not a printable character */ - else if (ucs == 0xfeff || (ucs >= 0x200b && ucs <= 0x200f)) - return -2; /* Zero-width space */ /* * UNI_DIRECT_BASE indicates the start of the region in the User Zone * which always has a 1:1 mapping to the currently loaded font. The diff --git a/drivers/tty/vt/gen_ucs_fallback_table.py b/drivers/tty/vt/gen_ucs_fallback_table.py new file mode 100755 index 000000000000..6e09c1cb6d4b --- /dev/null +++ b/drivers/tty/vt/gen_ucs_fallback_table.py @@ -0,0 +1,360 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# +# Leverage Python's unidecode module to generate ucs_fallback_table.h +# +# The generated table maps complex characters to their simpler fallback forms +# for a terminal display when corresponding glyphs are unavailable. +# +# Usage: +# python3 gen_ucs_fallback_table.py # Generate fallback tables +# python3 gen_ucs_fallback_table.py -o FILE # Specify output file + +import unicodedata +from unidecode import unidecode +import sys +import argparse +from collections import defaultdict + +# Try to get unidecode version +try: + from importlib.metadata import version + unidecode_version = version('unidecode') +except: + unidecode_version = 'unknown' + +# This script's file name +from pathlib import Path +this_file = Path(__file__).name + +# Default output file name +DEFAULT_OUT_FILE = "ucs_fallback_table.h" + +# Define the range marker value +RANGE_MARKER = 0x00 + +def generate_fallback_map(): + """Generate a fallback map using unidecode for all relevant Unicode points.""" + fallback_map = {} + + # Process BMP characters (0x0000 - 0xFFFF) to keep table size manageable + for cp in range(0x0080, 0x10000): # Skip ASCII range (0x00-0x7F) + char = chr(cp) + + # Skip unassigned/control characters + try: + if not unicodedata.name(char, ''): + continue + except ValueError: + continue + + # Get the unidecode transliteration + ascii_version = unidecode(char) + + # Only store if it results in a single character mapping + if len(ascii_version) == 1: + fallback_map[cp] = ord(ascii_version) + + # Apply manual overrides for special cases + fallback_map.update(get_special_overrides()) + + return fallback_map + +def get_special_overrides(): + """Get special case overrides that need different handling than unidecode + provides... or doesn't provide at all.""" + + overrides = {} + + # Multi-character unidecode output + # These map to single chars instead of unidecode's multiple-char mappings + # In a terminal fallback context, we need a single character rather than multiple + overrides[0x00C6] = ord('E') # Æ LATIN CAPITAL LETTER AE -> E (unidecode: "AE") + overrides[0x00E6] = ord('e') # æ LATIN SMALL LETTER AE -> e (unidecode: "ae") + overrides[0x0152] = ord('E') # Œ LATIN CAPITAL LIGATURE OE -> E (unidecode: "OE") + overrides[0x0153] = ord('e') # œ LATIN SMALL LETTER LIGATURE OE -> e (unidecode: "oe") + overrides[0x00DF] = ord('s') # ß LATIN SMALL LETTER SHARP S -> s (unidecode: "ss") + + # Comparison operators that unidecode renders as multiple characters + overrides[0x2264] = ord('<') # ≤ LESS-THAN OR EQUAL TO -> < (unidecode: "<=") + overrides[0x2265] = ord('>') # ≥ GREATER-THAN OR EQUAL TO -> > (unidecode: ">=") + + # Unidecode returns an empty string for these + overrides[0x2260] = ord('#') # ≠ NOT EQUAL TO -> # (unidecode: empty string) + + # Quadrant block characters that unidecode doesn't map + for cp in range(0x2596, 0x259F+1): + overrides[cp] = ord('#') # ▖ ▗ ▘ ▙ etc. - map to # (unidecode: empty string) + + # Directional arrows + # These provide better semantic meaning than unidecode's mappings + overrides[0x2192] = ord('>') # → RIGHTWARDS ARROW -> > (unidecode: "-") + overrides[0x2190] = ord('<') # ← LEFTWARDS ARROW -> < (unidecode: "-") + overrides[0x2191] = ord('^') # ↑ UPWARDS ARROW -> ^ (unidecode: "|") + overrides[0x2193] = ord('v') # ↓ DOWNWARDS ARROW -> v (unidecode: "|") + + # Double arrows with their directional semantic mappings + overrides[0x21D0] = ord('<') # ⇐ LEFTWARDS DOUBLE ARROW -> < + overrides[0x21D1] = ord('^') # ⇑ UPWARDS DOUBLE ARROW -> ^ + overrides[0x21D2] = ord('>') # ⇒ RIGHTWARDS DOUBLE ARROW -> > + overrides[0x21D3] = ord('v') # ⇓ DOWNWARDS DOUBLE ARROW -> v + + # Halfwidth arrows + # These need the same treatment as their normal-width counterparts + overrides[0xFFE9] = ord('<') # ← HALFWIDTH LEFTWARDS ARROW -> < (unidecode: "-") + overrides[0xFFEA] = ord('^') # ↑ HALFWIDTH UPWARDS ARROW -> ^ (unidecode: "|") + overrides[0xFFEB] = ord('>') # → HALFWIDTH RIGHTWARDS ARROW -> > (unidecode: "-") + overrides[0xFFEC] = ord('v') # ↓ HALFWIDTH DOWNWARDS ARROW -> v (unidecode: "|") + + # Currency symbols - each mapped to a representative letter + overrides[0x00A2] = ord('c') # ¢ CENT SIGN -> c + overrides[0x00A3] = ord('L') # £ POUND SIGN -> L + overrides[0x00A5] = ord('Y') # ¥ YEN SIGN -> Y + overrides[0x20AC] = ord('E') # € EURO SIGN -> E + + # Symbols mapped to letters + overrides[0x00A7] = ord('S') # § SECTION SIGN -> S + overrides[0x00A9] = ord('C') # © COPYRIGHT SIGN -> C + overrides[0x00AE] = ord('R') # ® REGISTERED SIGN -> R + overrides[0x2122] = ord('T') # ™ TRADE MARK SIGN -> T + + # Degree-related symbols + overrides[0x00B0] = ord('o') # ° DEGREE SIGN -> o + overrides[0x2103] = ord('C') # ℃ DEGREE CELSIUS -> C + overrides[0x2109] = ord('F') # ℉ DEGREE FAHRENHEIT -> F + + # Angle quotation marks + overrides[0x00AB] = ord('<') # « LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -> < + overrides[0x00BB] = ord('>') # » RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -> > + + # Operators with circular shape + overrides[0x2218] = ord('o') # ∘ RING OPERATOR -> o + overrides[0x2219] = ord('.') # ∙ BULLET OPERATOR -> . + + # Negated mathematical symbols (preserving the negation semantics) + # Negated symbols mapped to exclamation mark (semantically "not") + for cp in (0x2204, 0x2209, 0x220C, 0x2224, 0x2226, 0x226E, 0x226F, 0x2280, 0x2281, 0x2284, 0x2285): + overrides[cp] = ord('!') # Negated math symbols -> ! (not) + + # Negated symbols mapped to hash sign (semantically "not equal") + for cp in (0x2241, 0x2244, 0x2249, 0x2262, 0x2268, 0x2269, 0x226D, 0x228A, 0x228B): + overrides[cp] = ord('#') # Negated equality symbols -> # (not equal) + + # Negated arrows - all mapped to exclamation mark + for cp in (0x219A, 0x219B, 0x21AE, 0x21CD, 0x21CE, 0x21CF): + overrides[cp] = ord('!') # Negated arrows -> ! (not) + + # Dashes and hyphens + for cp in (0x2010, 0x2011, 0x2012, 0x2013, 0x2014, 0x2015, 0x2043, 0x2052): + overrides[cp] = ord('-') # Dashes and hyphens -> - + + # Question mark punctuation + for cp in (0x203D, 0x2047, 0x2048): + overrides[cp] = ord('?') # Question marks -> ? + + # Exclamation mark punctuation + for cp in (0x203C, 0x2049): + overrides[cp] = ord('!') # Exclamation marks -> ! + + # Asterisk-like symbols + for cp in (0x2042, 0x2051, 0x2055): + overrides[cp] = ord('*') + + # Other specific punctuation with unique mappings + overrides[0x201E] = ord('"') # „ DOUBLE LOW-9 QUOTATION MARK + overrides[0x2023] = ord('>') # ‣ TRIANGULAR BULLET + overrides[0x2026] = ord('.') # … HORIZONTAL ELLIPSIS + overrides[0x2033] = ord('"') # ″ DOUBLE PRIME + overrides[0x204B] = ord('P') # ⁋ REVERSED PILCROW SIGN + overrides[0x204C] = ord('<') # ⁌ BLACK LEFTWARDS BULLET + overrides[0x204D] = ord('>') # ⁍ BLACK RIGHTWARDS BULLET + overrides[0x204F] = ord(';') # ⁏ REVERSED SEMICOLON + overrides[0x205B] = ord(':') # ⁛ FOUR DOT MARK + + # Check marks + overrides[0x2713] = ord('v') # ✓ CHECK MARK + overrides[0x2714] = ord('V') # ✔ HEAVY CHECK MARK + + # X marks - lowercase for regular, uppercase for heavy + for cp in (0x2715, 0x2717): + overrides[cp] = ord('x') # Regular X marks -> x + for cp in (0x2716, 0x2718): + overrides[cp] = ord('X') # Heavy X marks -> X + + # Stars and asterisk-like symbols mapped to '*' + for cp in (0x2605, 0x2606, 0x262A, 0x269D, 0x2698): + overrides[cp] = ord('*') # All star and asterisk symbols -> * + for cp in range(0x2721, 0x2746+1): + overrides[cp] = ord('*') # All star and asterisk symbols -> * + for cp in range(0x2749, 0x274B+1): + overrides[cp] = ord('*') # Last set of asterisk symbols -> * + for cp in (0x229B, 0x22C6, 0x235F, 0x2363): + overrides[cp] = ord('*') # Star operators -> * + + # Special exclusions with fallback value of 0 + # These will be filtered out in organize_by_pages() + + # Exclude U+2028 (LINE SEPARATOR) + overrides[0x2028] = 0 # LINE SEPARATOR (unidecode: '\n') + + # Full-width to ASCII mapping (covering all printable ASCII 33-126) + # 0xFF01 (!) to 0xFF5E (~) -> ASCII 33 (!) to 126 (~) + # Those are excluded here to reduce the table size. + # It is more efficient to process them programmatically in + # ucs.c:ucs_get_fallback(). + for cp in range(0xFF01, 0xFF5E + 1): + overrides[cp] = 0 # Double-width ASCII characters + + return overrides + +def organize_by_pages(fallback_map): + """Organize the fallback mappings by their high byte (page).""" + # Group by high byte (page) + page_groups = defaultdict(list) + for code, fallback in fallback_map.items(): + # Skip characters with fallback value of 0 (excluded characters) + if fallback == 0: + continue + + page = code >> 8 # Get the high byte (page) + offset = code & 0xFF # Get the low byte (offset within page) + page_groups[page].append((offset, fallback)) + + # Sort each page's entries by offset + for page in page_groups: + page_groups[page].sort() + + return page_groups + +def compress_ranges(page_groups): + """Compress consecutive entries with the same fallback character into ranges. + A range is only compressed if it contains 3 or more consecutive entries.""" + + compressed_pages = {} + + for page, entries in page_groups.items(): + compressed_entries = [] + i = 0 + while i < len(entries): + start_offset, fallback = entries[i] + + # Look ahead to find consecutive entries with the same fallback + j = i + 1 + while (j < len(entries) and + entries[j][0] == entries[j-1][0] + 1 and # consecutive offsets + entries[j][1] == fallback): # same fallback + j += 1 + + # Calculate the range end + end_offset = entries[j-1][0] + + # If we found a range with 3 or more entries (worth compressing) + if j - i >= 3: + # Add a range entry + compressed_entries.append((start_offset, RANGE_MARKER)) + compressed_entries.append((end_offset, fallback)) + else: + # Add the individual entries as is + for k in range(i, j): + compressed_entries.append(entries[k]) + + i = j + + compressed_pages[page] = compressed_entries + + return compressed_pages + +def cp_name(cp): + """Get the Unicode character name for a code point.""" + try: + return unicodedata.name(chr(cp)) + except: + return f"U+{cp:04X}" + +def generate_fallback_tables(out_file=DEFAULT_OUT_FILE): + """Generate the fallback character tables.""" + # Generate fallback map using unidecode + fallback_map = generate_fallback_map() + print(f"Generated {len(fallback_map)} total fallback mappings") + + # Organize by pages + page_groups = organize_by_pages(fallback_map) + print(f"Organized into {len(page_groups)} pages") + + # Compress ranges + compressed_pages = compress_ranges(page_groups) + total_compressed_entries = sum(len(entries) for entries in compressed_pages.values()) + print(f"Total compressed entries: {total_compressed_entries}") + + # Create output file + with open(out_file, 'w') as f: + f.write(f"""\ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * {out_file} - Unicode character fallback table + * + * Auto-generated by {this_file} + * + * Unicode Version: {unicodedata.unidata_version} + * Unidecode Version: {unidecode_version} + * + * This file contains optimized tables that map complex Unicode characters + * to simpler fallback characters for terminal display when corresponding + * glyphs are unavailable. + */ + +static const struct ucs_page_desc ucs_fallback_pages[] = {{ +""") + + # Convert compressed_pages to a sorted list of (page, entries) tuples + sorted_pages = sorted(compressed_pages.items()) + + # Track the start index for each page + start_index = 0 + + # Write page descriptors + for page, entries in sorted_pages: + count = len(entries) + f.write(f"\t{{ 0x{page:02X}, {count}, {start_index} }},\n") + start_index += count + + # Write entries array + f.write("""\ +}; + +/* Page entries array (referenced by page descriptors) */ +static const struct ucs_page_entry ucs_fallback_entries[] = { +""") + + # Write all entries + for page, entries in sorted_pages: + page_hex = f"0x{page:02X}" + f.write(f"\t/* Entries for page {page_hex} */\n") + + for i, (offset, fallback) in enumerate(entries): + # Convert to hex for better readability + offset_hex = f"0x{offset:02X}" + fallback_hex = f"0x{fallback:02X}" + + # Handle comments + codepoint = (page << 8) | offset + + if fallback == RANGE_MARKER: + comment = f"{cp_name(codepoint)} -> ..." + else: + comment = f"{cp_name(codepoint)} -> '{chr(fallback)}'" + f.write(f"\t{{ 0x{offset:02X}, 0x{fallback:02X} }}, /* {comment} */\n") + + f.write(f"""\ +}}; + +#define UCS_PAGE_ENTRY_RANGE_MARKER {RANGE_MARKER} +""") + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Generate Unicode fallback character tables") + parser.add_argument("-o", "--output", dest="output_file", default=DEFAULT_OUT_FILE, + help=f"Output file name (default: {DEFAULT_OUT_FILE})") + args = parser.parse_args() + + generate_fallback_tables(out_file=args.output_file) diff --git a/drivers/tty/vt/gen_ucs_recompose_table.py b/drivers/tty/vt/gen_ucs_recompose_table.py new file mode 100755 index 000000000000..4434a436ac9e --- /dev/null +++ b/drivers/tty/vt/gen_ucs_recompose_table.py @@ -0,0 +1,257 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# +# Leverage Python's unicodedata module to generate ucs_recompose_table.h +# +# The generated table maps base character + combining mark pairs to their +# precomposed equivalents. +# +# Usage: +# python3 gen_ucs_recompose_table.py # Generate with common recomposition pairs +# python3 gen_ucs_recompose_table.py --full # Generate with all recomposition pairs + +import unicodedata +import sys +import argparse +import textwrap + +# This script's file name +from pathlib import Path +this_file = Path(__file__).name + +# Default output file name +DEFAULT_OUT_FILE = "ucs_recompose_table.h" + +common_recompose_description = "most commonly used Latin, Greek, and Cyrillic recomposition pairs only" +COMMON_RECOMPOSITION_PAIRS = [ + # Latin letters with accents - uppercase + (0x0041, 0x0300, 0x00C0), # A + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER A WITH GRAVE + (0x0041, 0x0301, 0x00C1), # A + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER A WITH ACUTE + (0x0041, 0x0302, 0x00C2), # A + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER A WITH CIRCUMFLEX + (0x0041, 0x0303, 0x00C3), # A + COMBINING TILDE = LATIN CAPITAL LETTER A WITH TILDE + (0x0041, 0x0308, 0x00C4), # A + COMBINING DIAERESIS = LATIN CAPITAL LETTER A WITH DIAERESIS + (0x0041, 0x030A, 0x00C5), # A + COMBINING RING ABOVE = LATIN CAPITAL LETTER A WITH RING ABOVE + (0x0043, 0x0327, 0x00C7), # C + COMBINING CEDILLA = LATIN CAPITAL LETTER C WITH CEDILLA + (0x0045, 0x0300, 0x00C8), # E + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER E WITH GRAVE + (0x0045, 0x0301, 0x00C9), # E + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER E WITH ACUTE + (0x0045, 0x0302, 0x00CA), # E + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER E WITH CIRCUMFLEX + (0x0045, 0x0308, 0x00CB), # E + COMBINING DIAERESIS = LATIN CAPITAL LETTER E WITH DIAERESIS + (0x0049, 0x0300, 0x00CC), # I + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER I WITH GRAVE + (0x0049, 0x0301, 0x00CD), # I + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER I WITH ACUTE + (0x0049, 0x0302, 0x00CE), # I + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER I WITH CIRCUMFLEX + (0x0049, 0x0308, 0x00CF), # I + COMBINING DIAERESIS = LATIN CAPITAL LETTER I WITH DIAERESIS + (0x004E, 0x0303, 0x00D1), # N + COMBINING TILDE = LATIN CAPITAL LETTER N WITH TILDE + (0x004F, 0x0300, 0x00D2), # O + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER O WITH GRAVE + (0x004F, 0x0301, 0x00D3), # O + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER O WITH ACUTE + (0x004F, 0x0302, 0x00D4), # O + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER O WITH CIRCUMFLEX + (0x004F, 0x0303, 0x00D5), # O + COMBINING TILDE = LATIN CAPITAL LETTER O WITH TILDE + (0x004F, 0x0308, 0x00D6), # O + COMBINING DIAERESIS = LATIN CAPITAL LETTER O WITH DIAERESIS + (0x0055, 0x0300, 0x00D9), # U + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER U WITH GRAVE + (0x0055, 0x0301, 0x00DA), # U + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER U WITH ACUTE + (0x0055, 0x0302, 0x00DB), # U + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER U WITH CIRCUMFLEX + (0x0055, 0x0308, 0x00DC), # U + COMBINING DIAERESIS = LATIN CAPITAL LETTER U WITH DIAERESIS + (0x0059, 0x0301, 0x00DD), # Y + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER Y WITH ACUTE + + # Latin letters with accents - lowercase + (0x0061, 0x0300, 0x00E0), # a + COMBINING GRAVE ACCENT = LATIN SMALL LETTER A WITH GRAVE + (0x0061, 0x0301, 0x00E1), # a + COMBINING ACUTE ACCENT = LATIN SMALL LETTER A WITH ACUTE + (0x0061, 0x0302, 0x00E2), # a + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER A WITH CIRCUMFLEX + (0x0061, 0x0303, 0x00E3), # a + COMBINING TILDE = LATIN SMALL LETTER A WITH TILDE + (0x0061, 0x0308, 0x00E4), # a + COMBINING DIAERESIS = LATIN SMALL LETTER A WITH DIAERESIS + (0x0061, 0x030A, 0x00E5), # a + COMBINING RING ABOVE = LATIN SMALL LETTER A WITH RING ABOVE + (0x0063, 0x0327, 0x00E7), # c + COMBINING CEDILLA = LATIN SMALL LETTER C WITH CEDILLA + (0x0065, 0x0300, 0x00E8), # e + COMBINING GRAVE ACCENT = LATIN SMALL LETTER E WITH GRAVE + (0x0065, 0x0301, 0x00E9), # e + COMBINING ACUTE ACCENT = LATIN SMALL LETTER E WITH ACUTE + (0x0065, 0x0302, 0x00EA), # e + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER E WITH CIRCUMFLEX + (0x0065, 0x0308, 0x00EB), # e + COMBINING DIAERESIS = LATIN SMALL LETTER E WITH DIAERESIS + (0x0069, 0x0300, 0x00EC), # i + COMBINING GRAVE ACCENT = LATIN SMALL LETTER I WITH GRAVE + (0x0069, 0x0301, 0x00ED), # i + COMBINING ACUTE ACCENT = LATIN SMALL LETTER I WITH ACUTE + (0x0069, 0x0302, 0x00EE), # i + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER I WITH CIRCUMFLEX + (0x0069, 0x0308, 0x00EF), # i + COMBINING DIAERESIS = LATIN SMALL LETTER I WITH DIAERESIS + (0x006E, 0x0303, 0x00F1), # n + COMBINING TILDE = LATIN SMALL LETTER N WITH TILDE + (0x006F, 0x0300, 0x00F2), # o + COMBINING GRAVE ACCENT = LATIN SMALL LETTER O WITH GRAVE + (0x006F, 0x0301, 0x00F3), # o + COMBINING ACUTE ACCENT = LATIN SMALL LETTER O WITH ACUTE + (0x006F, 0x0302, 0x00F4), # o + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER O WITH CIRCUMFLEX + (0x006F, 0x0303, 0x00F5), # o + COMBINING TILDE = LATIN SMALL LETTER O WITH TILDE + (0x006F, 0x0308, 0x00F6), # o + COMBINING DIAERESIS = LATIN SMALL LETTER O WITH DIAERESIS + (0x0075, 0x0300, 0x00F9), # u + COMBINING GRAVE ACCENT = LATIN SMALL LETTER U WITH GRAVE + (0x0075, 0x0301, 0x00FA), # u + COMBINING ACUTE ACCENT = LATIN SMALL LETTER U WITH ACUTE + (0x0075, 0x0302, 0x00FB), # u + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER U WITH CIRCUMFLEX + (0x0075, 0x0308, 0x00FC), # u + COMBINING DIAERESIS = LATIN SMALL LETTER U WITH DIAERESIS + (0x0079, 0x0301, 0x00FD), # y + COMBINING ACUTE ACCENT = LATIN SMALL LETTER Y WITH ACUTE + (0x0079, 0x0308, 0x00FF), # y + COMBINING DIAERESIS = LATIN SMALL LETTER Y WITH DIAERESIS + + # Common Greek characters + (0x0391, 0x0301, 0x0386), # Α + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER ALPHA WITH TONOS + (0x0395, 0x0301, 0x0388), # Ε + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER EPSILON WITH TONOS + (0x0397, 0x0301, 0x0389), # Η + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER ETA WITH TONOS + (0x0399, 0x0301, 0x038A), # Ι + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER IOTA WITH TONOS + (0x039F, 0x0301, 0x038C), # Ο + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER OMICRON WITH TONOS + (0x03A5, 0x0301, 0x038E), # Υ + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER UPSILON WITH TONOS + (0x03A9, 0x0301, 0x038F), # Ω + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER OMEGA WITH TONOS + (0x03B1, 0x0301, 0x03AC), # α + COMBINING ACUTE ACCENT = GREEK SMALL LETTER ALPHA WITH TONOS + (0x03B5, 0x0301, 0x03AD), # ε + COMBINING ACUTE ACCENT = GREEK SMALL LETTER EPSILON WITH TONOS + (0x03B7, 0x0301, 0x03AE), # η + COMBINING ACUTE ACCENT = GREEK SMALL LETTER ETA WITH TONOS + (0x03B9, 0x0301, 0x03AF), # ι + COMBINING ACUTE ACCENT = GREEK SMALL LETTER IOTA WITH TONOS + (0x03BF, 0x0301, 0x03CC), # ο + COMBINING ACUTE ACCENT = GREEK SMALL LETTER OMICRON WITH TONOS + (0x03C5, 0x0301, 0x03CD), # υ + COMBINING ACUTE ACCENT = GREEK SMALL LETTER UPSILON WITH TONOS + (0x03C9, 0x0301, 0x03CE), # ω + COMBINING ACUTE ACCENT = GREEK SMALL LETTER OMEGA WITH TONOS + + # Common Cyrillic characters + (0x0418, 0x0306, 0x0419), # И + COMBINING BREVE = CYRILLIC CAPITAL LETTER SHORT I + (0x0438, 0x0306, 0x0439), # и + COMBINING BREVE = CYRILLIC SMALL LETTER SHORT I + (0x0423, 0x0306, 0x040E), # У + COMBINING BREVE = CYRILLIC CAPITAL LETTER SHORT U + (0x0443, 0x0306, 0x045E), # у + COMBINING BREVE = CYRILLIC SMALL LETTER SHORT U +] + +full_recompose_description = "all possible recomposition pairs from the Unicode BMP" +def collect_all_recomposition_pairs(): + """Collect all possible recomposition pairs from the Unicode data.""" + # Map to store recomposition pairs: (base, combining) -> recomposed + recompose_map = {} + + # Process all assigned Unicode code points in BMP (Basic Multilingual Plane) + # We limit to BMP (0x0000-0xFFFF) to keep our table smaller with uint16_t + for cp in range(0, 0x10000): + try: + char = chr(cp) + + # Skip unassigned or control characters + if not unicodedata.name(char, ''): + continue + + # Find decomposition + decomp = unicodedata.decomposition(char) + if not decomp or '<' in decomp: # Skip compatibility decompositions + continue + + # Parse the decomposition + parts = decomp.split() + if len(parts) == 2: # Simple base + combining mark + base = int(parts[0], 16) + combining = int(parts[1], 16) + + # Only store if both are in BMP + if base < 0x10000 and combining < 0x10000: + recompose_map[(base, combining)] = cp + + except (ValueError, TypeError): + continue + + # Convert to a list of tuples and sort for binary search + recompose_list = [(base, combining, recomposed) + for (base, combining), recomposed in recompose_map.items()] + recompose_list.sort() + + return recompose_list + +def validate_common_pairs(full_list): + """Validate that all common pairs are in the full list. + + Raises: + ValueError: If any common pair is missing or has a different recomposition + value than what's in the full table. + """ + full_pairs = {(base, combining): recomposed for base, combining, recomposed in full_list} + for base, combining, recomposed in COMMON_RECOMPOSITION_PAIRS: + full_recomposed = full_pairs.get((base, combining)) + if full_recomposed is None: + error_msg = f"Error: Common pair (0x{base:04X}, 0x{combining:04X}) not found in full data" + print(error_msg) + raise ValueError(error_msg) + elif full_recomposed != recomposed: + error_msg = (f"Error: Common pair (0x{base:04X}, 0x{combining:04X}) has different recomposition: " + f"0x{recomposed:04X} vs 0x{full_recomposed:04X}") + print(error_msg) + raise ValueError(error_msg) + +def generate_recomposition_table(use_full_list=False, out_file=DEFAULT_OUT_FILE): + """Generate the recomposition C table.""" + + # Collect all recomposition pairs for validation + full_recompose_list = collect_all_recomposition_pairs() + + # Decide which list to use + if use_full_list: + print("Using full recomposition list...") + recompose_list = full_recompose_list + table_description = full_recompose_description + alt_list = COMMON_RECOMPOSITION_PAIRS + alt_description = common_recompose_description + else: + print("Using common recomposition list...") + # Validate that all common pairs are in the full list + validate_common_pairs(full_recompose_list) + recompose_list = sorted(COMMON_RECOMPOSITION_PAIRS) + table_description = common_recompose_description + alt_list = full_recompose_list + alt_description = full_recompose_description + generation_mode = " --full" if use_full_list else "" + alternative_mode = " --full" if not use_full_list else "" + table_description_detail = f"{table_description} ({len(recompose_list)} entries)" + alt_description_detail = f"{alt_description} ({len(alt_list)} entries)" + + # Calculate min/max values for boundary checks + min_base = min(base for base, _, _ in recompose_list) + max_base = max(base for base, _, _ in recompose_list) + min_combining = min(combining for _, combining, _ in recompose_list) + max_combining = max(combining for _, combining, _ in recompose_list) + + # Generate implementation file + with open(out_file, 'w') as f: + f.write(f"""\ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * {out_file} - Unicode character recomposition + * + * Auto-generated by {this_file}{generation_mode} + * + * Unicode Version: {unicodedata.unidata_version} + * +{textwrap.fill( + f"This file contains a table with {table_description_detail}. " + + f"To generate a table with {alt_description_detail} instead, run:", + width=75, initial_indent=" * ", subsequent_indent=" * ")} + * + * python3 {this_file}{alternative_mode} + */ + +/* + * Table of {table_description} + * Sorted by base character and then combining mark for binary search + */ +static const struct ucs_recomposition ucs_recomposition_table[] = {{ +""") + + for base, combining, recomposed in recompose_list: + try: + base_name = unicodedata.name(chr(base)) + combining_name = unicodedata.name(chr(combining)) + recomposed_name = unicodedata.name(chr(recomposed)) + comment = f"/* {base_name} + {combining_name} = {recomposed_name} */" + except ValueError: + comment = f"/* U+{base:04X} + U+{combining:04X} = U+{recomposed:04X} */" + f.write(f"\t{{ 0x{base:04X}, 0x{combining:04X}, 0x{recomposed:04X} }}, {comment}\n") + + f.write(f"""\ +}}; + +/* + * Boundary values for quick rejection + * These are calculated by analyzing the table during generation + */ +#define UCS_RECOMPOSE_MIN_BASE 0x{min_base:04X} +#define UCS_RECOMPOSE_MAX_BASE 0x{max_base:04X} +#define UCS_RECOMPOSE_MIN_MARK 0x{min_combining:04X} +#define UCS_RECOMPOSE_MAX_MARK 0x{max_combining:04X} +""") + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Generate Unicode recomposition table") + parser.add_argument("--full", action="store_true", + help="Generate a full recomposition table (default: common pairs only)") + parser.add_argument("-o", "--output", dest="output_file", default=DEFAULT_OUT_FILE, + help=f"Output file name (default: {DEFAULT_OUT_FILE})") + args = parser.parse_args() + + generate_recomposition_table(use_full_list=args.full, out_file=args.output_file) diff --git a/drivers/tty/vt/gen_ucs_width_table.py b/drivers/tty/vt/gen_ucs_width_table.py new file mode 100755 index 000000000000..76e80ebeff13 --- /dev/null +++ b/drivers/tty/vt/gen_ucs_width_table.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0 +# +# Leverage Python's unicodedata module to generate ucs_width_table.h + +import unicodedata +import sys +import argparse + +# This script's file name +from pathlib import Path +this_file = Path(__file__).name + +# Default output file name +DEFAULT_OUT_FILE = "ucs_width_table.h" + +# --- Global Constants for Width Assignments --- + +# Known zero-width characters +KNOWN_ZERO_WIDTH = ( + 0x200B, # ZERO WIDTH SPACE + 0x200C, # ZERO WIDTH NON-JOINER + 0x200D, # ZERO WIDTH JOINER + 0x2060, # WORD JOINER + 0xFEFF # ZERO WIDTH NO-BREAK SPACE (BOM) +) + +# Zero-width emoji modifiers and components +# NOTE: Some of these characters would normally be single-width according to +# East Asian Width properties, but we deliberately override them to be +# zero-width because they function as modifiers in emoji sequences. +EMOJI_ZERO_WIDTH = [ + # Skin tone modifiers + (0x1F3FB, 0x1F3FF), # Emoji modifiers (skin tones) + + # Variation selectors (note: VS16 is treated specially in vt.c) + (0xFE00, 0xFE0F), # Variation Selectors 1-16 + + # Gender and hair style modifiers + # These would be single-width by Unicode properties, but are zero-width + # when part of emoji + (0x2640, 0x2640), # Female sign + (0x2642, 0x2642), # Male sign + (0x26A7, 0x26A7), # Transgender symbol + (0x1F9B0, 0x1F9B3), # Hair components (red, curly, white, bald) + + # Tag characters + (0xE0020, 0xE007E), # Tags +] + +# Regional indicators (flag components) +REGIONAL_INDICATORS = (0x1F1E6, 0x1F1FF) # Regional indicator symbols A-Z + +# Double-width emoji ranges +# +# Many emoji characters are classified as single-width according to Unicode +# Standard Annex #11 East Asian Width property (N or Neutral), but we +# deliberately override them to be double-width. References: +# 1. Unicode Technical Standard #51: Unicode Emoji +# (https://www.unicode.org/reports/tr51/) +# 2. Principle of "emoji presentation" in WHATWG CSS Text specification +# (https://drafts.csswg.org/css-text-3/#character-properties) +# 3. Terminal emulator implementations (iTerm2, Windows Terminal, etc.) which +# universally render emoji as double-width characters regardless of their +# Unicode EAW property +# 4. W3C Work Item: Requirements for Japanese Text Layout - Section 3.8.1 +# Emoji width (https://www.w3.org/TR/jlreq/) +EMOJI_RANGES = [ + (0x1F000, 0x1F02F), # Mahjong Tiles (EAW: N, but displayed as double-width) + (0x1F0A0, 0x1F0FF), # Playing Cards (EAW: N, but displayed as double-width) + (0x1F300, 0x1F5FF), # Miscellaneous Symbols and Pictographs + (0x1F600, 0x1F64F), # Emoticons + (0x1F680, 0x1F6FF), # Transport and Map Symbols + (0x1F700, 0x1F77F), # Alchemical Symbols + (0x1F780, 0x1F7FF), # Geometric Shapes Extended + (0x1F800, 0x1F8FF), # Supplemental Arrows-C + (0x1F900, 0x1F9FF), # Supplemental Symbols and Pictographs + (0x1FA00, 0x1FA6F), # Chess Symbols + (0x1FA70, 0x1FAFF), # Symbols and Pictographs Extended-A +] + +def create_width_tables(): + """ + Creates Unicode character width tables and returns the data structures. + + Returns: + tuple: (zero_width_ranges, double_width_ranges) + """ + + # Width data mapping + width_map = {} # Maps code points to width (0, 1, 2) + + # Mark emoji modifiers as zero-width + for start, end in EMOJI_ZERO_WIDTH: + for cp in range(start, end + 1): + width_map[cp] = 0 + + # Mark all regional indicators as single-width as they are usually paired + # providing a combined width of 2 when displayed together. + start, end = REGIONAL_INDICATORS + for cp in range(start, end + 1): + width_map[cp] = 1 + + # Process all assigned Unicode code points (Basic Multilingual Plane + + # Supplementary Planes) Range 0x0 to 0x10FFFF (the full Unicode range) + for block_start in range(0, 0x110000, 0x1000): + block_end = block_start + 0x1000 + for cp in range(block_start, block_end): + try: + char = chr(cp) + + # Skip if already processed + if cp in width_map: + continue + + # Check for combining marks and a format characters + category = unicodedata.category(char) + + # Combining marks + if category.startswith('M'): + width_map[cp] = 0 + continue + + # Format characters + # Since we have no support for bidirectional text, all format + # characters (category Cf) can be treated with width 0 (zero) + # for simplicity, as they don't need to occupy visual space + # in a non-bidirectional text environment. + if category == 'Cf': + width_map[cp] = 0 + continue + + # Known zero-width characters + if cp in KNOWN_ZERO_WIDTH: + width_map[cp] = 0 + continue + + # Use East Asian Width property + eaw = unicodedata.east_asian_width(char) + if eaw in ('F', 'W'): # Fullwidth or Wide + width_map[cp] = 2 + elif eaw in ('Na', 'H', 'N', 'A'): # Narrow, Halfwidth, Neutral, Ambiguous + width_map[cp] = 1 + else: + # Default to single-width for unknown + width_map[cp] = 1 + + except (ValueError, OverflowError): + # Skip invalid code points + continue + + # Process Emoji - generally double-width + for start, end in EMOJI_RANGES: + for cp in range(start, end + 1): + if cp not in width_map or width_map[cp] != 0: # Don't override zero-width + try: + char = chr(cp) + width_map[cp] = 2 + except (ValueError, OverflowError): + continue + + # Optimize to create range tables + def ranges_optimize(width_data, target_width): + points = sorted([cp for cp, width in width_data.items() if width == target_width]) + if not points: + return [] + + # Group consecutive code points into ranges + ranges = [] + start = points[0] + prev = start + + for cp in points[1:]: + if cp > prev + 1: + ranges.append((start, prev)) + start = cp + prev = cp + + # Add the last range + ranges.append((start, prev)) + return ranges + + # Extract ranges for each width + zero_width_ranges = ranges_optimize(width_map, 0) + double_width_ranges = ranges_optimize(width_map, 2) + + return zero_width_ranges, double_width_ranges + +def write_tables(zero_width_ranges, double_width_ranges, out_file=DEFAULT_OUT_FILE): + """ + Write the generated tables to C header file. + + Args: + zero_width_ranges: List of (start, end) ranges for zero-width characters + double_width_ranges: List of (start, end) ranges for double-width characters + out_file: Output file name (default: DEFAULT_OUT_FILE) + """ + + # Function to split ranges into BMP (16-bit) and non-BMP (above 16-bit) + def split_ranges_by_size(ranges): + bmp_ranges = [] + non_bmp_ranges = [] + + for start, end in ranges: + if end <= 0xFFFF: + bmp_ranges.append((start, end)) + elif start > 0xFFFF: + non_bmp_ranges.append((start, end)) + else: + # Split the range at 0xFFFF + bmp_ranges.append((start, 0xFFFF)) + non_bmp_ranges.append((0x10000, end)) + + return bmp_ranges, non_bmp_ranges + + # Split ranges into BMP and non-BMP + zero_width_bmp, zero_width_non_bmp = split_ranges_by_size(zero_width_ranges) + double_width_bmp, double_width_non_bmp = split_ranges_by_size(double_width_ranges) + + # Function to generate code point description comments + def get_code_point_comment(start, end): + try: + start_char_desc = unicodedata.name(chr(start)) + if start == end: + return f"/* {start_char_desc} */" + else: + end_char_desc = unicodedata.name(chr(end)) + return f"/* {start_char_desc} - {end_char_desc} */" + except: + if start == end: + return f"/* U+{start:04X} */" + else: + return f"/* U+{start:04X} - U+{end:04X} */" + + # Generate C tables + with open(out_file, 'w') as f: + f.write(f"""\ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * {out_file} - Unicode character width + * + * Auto-generated by {this_file} + * + * Unicode Version: {unicodedata.unidata_version} + */ + +/* Zero-width character ranges (BMP - Basic Multilingual Plane, U+0000 to U+FFFF) */ +static const struct ucs_interval16 ucs_zero_width_bmp_ranges[] = {{ +""") + + for start, end in zero_width_bmp: + comment = get_code_point_comment(start, end) + f.write(f"\t{{ 0x{start:04X}, 0x{end:04X} }}, {comment}\n") + + f.write("""\ +}; + +/* Zero-width character ranges (non-BMP, U+10000 and above) */ +static const struct ucs_interval32 ucs_zero_width_non_bmp_ranges[] = { +""") + + for start, end in zero_width_non_bmp: + comment = get_code_point_comment(start, end) + f.write(f"\t{{ 0x{start:05X}, 0x{end:05X} }}, {comment}\n") + + f.write("""\ +}; + +/* Double-width character ranges (BMP - Basic Multilingual Plane, U+0000 to U+FFFF) */ +static const struct ucs_interval16 ucs_double_width_bmp_ranges[] = { +""") + + for start, end in double_width_bmp: + comment = get_code_point_comment(start, end) + f.write(f"\t{{ 0x{start:04X}, 0x{end:04X} }}, {comment}\n") + + f.write("""\ +}; + +/* Double-width character ranges (non-BMP, U+10000 and above) */ +static const struct ucs_interval32 ucs_double_width_non_bmp_ranges[] = { +""") + + for start, end in double_width_non_bmp: + comment = get_code_point_comment(start, end) + f.write(f"\t{{ 0x{start:05X}, 0x{end:05X} }}, {comment}\n") + + f.write("};\n") + +if __name__ == "__main__": + # Parse command line arguments + parser = argparse.ArgumentParser(description="Generate Unicode width tables") + parser.add_argument("-o", "--output", dest="output_file", default=DEFAULT_OUT_FILE, + help=f"Output file name (default: {DEFAULT_OUT_FILE})") + args = parser.parse_args() + + # Write tables to header file + zero_width_ranges, double_width_ranges = create_width_tables() + write_tables(zero_width_ranges, double_width_ranges, out_file=args.output_file) + + # Print summary + zero_width_count = sum(end - start + 1 for start, end in zero_width_ranges) + double_width_count = sum(end - start + 1 for start, end in double_width_ranges) + print(f"Generated {args.output_file} with:") + print(f"- {len(zero_width_ranges)} zero-width ranges covering ~{zero_width_count} code points") + print(f"- {len(double_width_ranges)} double-width ranges covering ~{double_width_count} code points") + print(f"- Unicode Version: {unicodedata.unidata_version}") diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index ae92e6a50a65..dc585079c2fb 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c @@ -376,6 +376,17 @@ static void to_utf8(struct vc_data *vc, uint c) } } +static void put_queue_utf8(struct vc_data *vc, u32 value) +{ + if (kbd->kbdmode == VC_UNICODE) + to_utf8(vc, value); + else { + int c = conv_uni_to_8bit(value); + if (c != -1) + put_queue(vc, c); + } +} + /* FIXME: review locking for vt.c callers */ static void set_leds(void) { @@ -454,13 +465,7 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch) if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d) return d; - if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, d); - else { - int c = conv_uni_to_8bit(d); - if (c != -1) - put_queue(vc, c); - } + put_queue_utf8(vc, d); return ch; } @@ -471,13 +476,7 @@ static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch) static void fn_enter(struct vc_data *vc) { if (diacr) { - if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, diacr); - else { - int c = conv_uni_to_8bit(diacr); - if (c != -1) - put_queue(vc, c); - } + put_queue_utf8(vc, diacr); diacr = 0; } @@ -685,13 +684,7 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag) diacr = value; return; } - if (kbd->kbdmode == VC_UNICODE) - to_utf8(vc, value); - else { - int c = conv_uni_to_8bit(value); - if (c != -1) - put_queue(vc, c); - } + put_queue_utf8(vc, value); } /* @@ -1519,7 +1512,7 @@ static void kbd_keycode(unsigned int keycode, int down, bool hw_raw) if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT) return; - (*k_handler[type])(vc, keysym & 0xff, !down); + (*k_handler[type])(vc, KVAL(keysym), !down); param.ledstate = kbd->ledflagstate; atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m); diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c index 791e2f1f7c0b..24b0a53e5a79 100644 --- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -403,6 +403,12 @@ int paste_selection(struct tty_struct *tty) DECLARE_WAITQUEUE(wait, current); int ret = 0; + bool bp = vc->vc_bracketed_paste; + static const char bracketed_paste_start[] = "\033[200~"; + static const char bracketed_paste_end[] = "\033[201~"; + const char *bps = bp ? bracketed_paste_start : NULL; + const char *bpe = bp ? bracketed_paste_end : NULL; + console_lock(); poke_blanked_console(); console_unlock(); @@ -414,7 +420,7 @@ int paste_selection(struct tty_struct *tty) add_wait_queue(&vc->paste_wait, &wait); mutex_lock(&vc_sel.lock); - while (vc_sel.buffer && vc_sel.buf_len > pasted) { + while (vc_sel.buffer && (vc_sel.buf_len > pasted || bpe)) { set_current_state(TASK_INTERRUPTIBLE); if (signal_pending(current)) { ret = -EINTR; @@ -427,10 +433,27 @@ int paste_selection(struct tty_struct *tty) continue; } __set_current_state(TASK_RUNNING); + + if (bps) { + bps += tty_ldisc_receive_buf(ld, bps, NULL, strlen(bps)); + if (*bps != '\0') + continue; + bps = NULL; + } + count = vc_sel.buf_len - pasted; - count = tty_ldisc_receive_buf(ld, vc_sel.buffer + pasted, NULL, - count); - pasted += count; + if (count) { + pasted += tty_ldisc_receive_buf(ld, vc_sel.buffer + pasted, + NULL, count); + if (vc_sel.buf_len > pasted) + continue; + } + + if (bpe) { + bpe += tty_ldisc_receive_buf(ld, bpe, NULL, strlen(bpe)); + if (*bpe == '\0') + bpe = NULL; + } } mutex_unlock(&vc_sel.lock); remove_wait_queue(&vc->paste_wait, &wait); diff --git a/drivers/tty/vt/ucs.c b/drivers/tty/vt/ucs.c new file mode 100644 index 000000000000..6ead622b7713 --- /dev/null +++ b/drivers/tty/vt/ucs.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * ucs.c - Universal Character Set processing + */ + +#include <linux/array_size.h> +#include <linux/bsearch.h> +#include <linux/consolemap.h> +#include <linux/minmax.h> + +struct ucs_interval16 { + u16 first; + u16 last; +}; + +struct ucs_interval32 { + u32 first; + u32 last; +}; + +#include "ucs_width_table.h" + +static int interval16_cmp(const void *key, const void *element) +{ + u16 cp = *(u16 *)key; + const struct ucs_interval16 *entry = element; + + if (cp < entry->first) + return -1; + if (cp > entry->last) + return 1; + return 0; +} + +static int interval32_cmp(const void *key, const void *element) +{ + u32 cp = *(u32 *)key; + const struct ucs_interval32 *entry = element; + + if (cp < entry->first) + return -1; + if (cp > entry->last) + return 1; + return 0; +} + +static bool cp_in_range16(u16 cp, const struct ucs_interval16 *ranges, size_t size) +{ + if (cp < ranges[0].first || cp > ranges[size - 1].last) + return false; + + return __inline_bsearch(&cp, ranges, size, sizeof(*ranges), + interval16_cmp) != NULL; +} + +static bool cp_in_range32(u32 cp, const struct ucs_interval32 *ranges, size_t size) +{ + if (cp < ranges[0].first || cp > ranges[size - 1].last) + return false; + + return __inline_bsearch(&cp, ranges, size, sizeof(*ranges), + interval32_cmp) != NULL; +} + +#define UCS_IS_BMP(cp) ((cp) <= 0xffff) + +/** + * ucs_is_zero_width() - Determine if a Unicode code point is zero-width. + * @cp: Unicode code point (UCS-4) + * + * Return: true if the character is zero-width, false otherwise + */ +bool ucs_is_zero_width(u32 cp) +{ + if (UCS_IS_BMP(cp)) + return cp_in_range16(cp, ucs_zero_width_bmp_ranges, + ARRAY_SIZE(ucs_zero_width_bmp_ranges)); + else + return cp_in_range32(cp, ucs_zero_width_non_bmp_ranges, + ARRAY_SIZE(ucs_zero_width_non_bmp_ranges)); +} + +/** + * ucs_is_double_width() - Determine if a Unicode code point is double-width. + * @cp: Unicode code point (UCS-4) + * + * Return: true if the character is double-width, false otherwise + */ +bool ucs_is_double_width(u32 cp) +{ + if (UCS_IS_BMP(cp)) + return cp_in_range16(cp, ucs_double_width_bmp_ranges, + ARRAY_SIZE(ucs_double_width_bmp_ranges)); + else + return cp_in_range32(cp, ucs_double_width_non_bmp_ranges, + ARRAY_SIZE(ucs_double_width_non_bmp_ranges)); +} + +/* + * Structure for base with combining mark pairs and resulting recompositions. + * Using u16 to save space since all values are within BMP range. + */ +struct ucs_recomposition { + u16 base; /* base character */ + u16 mark; /* combining mark */ + u16 recomposed; /* corresponding recomposed character */ +}; + +#include "ucs_recompose_table.h" + +struct compare_key { + u16 base; + u16 mark; +}; + +static int recomposition_cmp(const void *key, const void *element) +{ + const struct compare_key *search_key = key; + const struct ucs_recomposition *entry = element; + + /* Compare base character first */ + if (search_key->base < entry->base) + return -1; + if (search_key->base > entry->base) + return 1; + + /* Base characters match, now compare combining character */ + if (search_key->mark < entry->mark) + return -1; + if (search_key->mark > entry->mark) + return 1; + + /* Both match */ + return 0; +} + +/** + * ucs_recompose() - Attempt to recompose two Unicode characters into a single character. + * @base: Base Unicode code point (UCS-4) + * @mark: Combining mark Unicode code point (UCS-4) + * + * Return: Recomposed Unicode code point, or 0 if no recomposition is possible + */ +u32 ucs_recompose(u32 base, u32 mark) +{ + /* Check if characters are within the range of our table */ + if (base < UCS_RECOMPOSE_MIN_BASE || base > UCS_RECOMPOSE_MAX_BASE || + mark < UCS_RECOMPOSE_MIN_MARK || mark > UCS_RECOMPOSE_MAX_MARK) + return 0; + + struct compare_key key = { base, mark }; + struct ucs_recomposition *result = + __inline_bsearch(&key, ucs_recomposition_table, + ARRAY_SIZE(ucs_recomposition_table), + sizeof(*ucs_recomposition_table), + recomposition_cmp); + + return result ? result->recomposed : 0; +} + +/* + * The fallback table structures implement a 2-level lookup. + */ + +struct ucs_page_desc { + u8 page; /* Page index (high byte of code points) */ + u8 count; /* Number of entries in this page */ + u16 start; /* Start index in entries array */ +}; + +struct ucs_page_entry { + u8 offset; /* Offset within page (0-255) */ + u8 fallback; /* Fallback character or range start marker */ +}; + +#include "ucs_fallback_table.h" + +static int ucs_page_desc_cmp(const void *key, const void *element) +{ + u8 page = *(u8 *)key; + const struct ucs_page_desc *entry = element; + + if (page < entry->page) + return -1; + if (page > entry->page) + return 1; + return 0; +} + +static int ucs_page_entry_cmp(const void *key, const void *element) +{ + u8 offset = *(u8 *)key; + const struct ucs_page_entry *entry = element; + + if (offset < entry->offset) + return -1; + if (entry->fallback == UCS_PAGE_ENTRY_RANGE_MARKER) { + if (offset > entry[1].offset) + return 1; + } else { + if (offset > entry->offset) + return 1; + } + return 0; +} + +/** + * ucs_get_fallback() - Get a substitution for the provided Unicode character + * @base: Base Unicode code point (UCS-4) + * + * Get a simpler fallback character for the provided Unicode character. + * This is used for terminal display when corresponding glyph is unavailable. + * The substitution may not be as good as the actual glyph for the original + * character but still way more helpful than a squared question mark. + * + * Return: Fallback Unicode code point, or 0 if none is available + */ +u32 ucs_get_fallback(u32 cp) +{ + const struct ucs_page_desc *page; + const struct ucs_page_entry *entry; + u8 page_idx = cp >> 8, offset = cp; + + if (!UCS_IS_BMP(cp)) + return 0; + + /* + * Full-width to ASCII mapping (covering all printable ASCII 33-126) + * 0xFF01 (!) to 0xFF5E (~) -> ASCII 33 (!) to 126 (~) + * We process them programmatically to reduce the table size. + */ + if (cp >= 0xFF01 && cp <= 0xFF5E) + return cp - 0xFF01 + 33; + + page = __inline_bsearch(&page_idx, ucs_fallback_pages, + ARRAY_SIZE(ucs_fallback_pages), + sizeof(*ucs_fallback_pages), + ucs_page_desc_cmp); + if (!page) + return 0; + + entry = __inline_bsearch(&offset, ucs_fallback_entries + page->start, + page->count, sizeof(*ucs_fallback_entries), + ucs_page_entry_cmp); + if (!entry) + return 0; + + if (entry->fallback == UCS_PAGE_ENTRY_RANGE_MARKER) + entry++; + return entry->fallback; +} diff --git a/drivers/tty/vt/ucs_fallback_table.h_shipped b/drivers/tty/vt/ucs_fallback_table.h_shipped new file mode 100644 index 000000000000..2da5a8fe1cf1 --- /dev/null +++ b/drivers/tty/vt/ucs_fallback_table.h_shipped @@ -0,0 +1,3346 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ucs_fallback_table.h - Unicode character fallback table + * + * Auto-generated by gen_ucs_fallback_table.py + * + * Unicode Version: 16.0.0 + * Unidecode Version: 1.3.8 + * + * This file contains optimized tables that map complex Unicode characters + * to simpler fallback characters for terminal display when corresponding + * glyphs are unavailable. + */ + +static const struct ucs_page_desc ucs_fallback_pages[] = { + { 0x00, 62, 0 }, + { 0x01, 218, 62 }, + { 0x02, 196, 280 }, + { 0x03, 96, 476 }, + { 0x04, 113, 572 }, + { 0x05, 100, 685 }, + { 0x06, 119, 785 }, + { 0x07, 91, 904 }, + { 0x09, 99, 995 }, + { 0x0A, 78, 1094 }, + { 0x0B, 79, 1172 }, + { 0x0C, 85, 1251 }, + { 0x0D, 73, 1336 }, + { 0x0E, 83, 1409 }, + { 0x0F, 69, 1492 }, + { 0x10, 93, 1561 }, + { 0x11, 51, 1654 }, + { 0x13, 22, 1705 }, + { 0x14, 30, 1727 }, + { 0x15, 17, 1757 }, + { 0x16, 81, 1774 }, + { 0x17, 47, 1855 }, + { 0x18, 96, 1902 }, + { 0x1D, 105, 1998 }, + { 0x1E, 246, 2103 }, + { 0x1F, 94, 2349 }, + { 0x20, 107, 2443 }, + { 0x21, 136, 2550 }, + { 0x22, 34, 2686 }, + { 0x23, 4, 2720 }, + { 0x24, 72, 2724 }, + { 0x25, 60, 2796 }, + { 0x26, 6, 2856 }, + { 0x27, 18, 2862 }, + { 0x28, 64, 2880 }, + { 0x29, 1, 2944 }, + { 0x2C, 15, 2945 }, + { 0x2E, 29, 2960 }, + { 0x30, 53, 2989 }, + { 0x31, 50, 3042 }, + { 0x32, 5, 3092 }, + { 0xA0, 4, 3097 }, + { 0xC5, 2, 3101 }, + { 0xC6, 2, 3103 }, + { 0xC7, 1, 3105 }, + { 0xFB, 35, 3106 }, + { 0xFE, 37, 3141 }, + { 0xFF, 50, 3178 }, +}; + +/* Page entries array (referenced by page descriptors) */ +static const struct ucs_page_entry ucs_fallback_entries[] = { + /* Entries for page 0x00 */ + { 0xA0, 0x20 }, /* NO-BREAK SPACE -> ' ' */ + { 0xA1, 0x21 }, /* INVERTED EXCLAMATION MARK -> '!' */ + { 0xA2, 0x63 }, /* CENT SIGN -> 'c' */ + { 0xA3, 0x4C }, /* POUND SIGN -> 'L' */ + { 0xA5, 0x59 }, /* YEN SIGN -> 'Y' */ + { 0xA6, 0x7C }, /* BROKEN BAR -> '|' */ + { 0xA7, 0x53 }, /* SECTION SIGN -> 'S' */ + { 0xA8, 0x22 }, /* DIAERESIS -> '"' */ + { 0xA9, 0x43 }, /* COPYRIGHT SIGN -> 'C' */ + { 0xAA, 0x61 }, /* FEMININE ORDINAL INDICATOR -> 'a' */ + { 0xAB, 0x3C }, /* LEFT-POINTING DOUBLE ANGLE QUOTATION MARK -> '<' */ + { 0xAC, 0x21 }, /* NOT SIGN -> '!' */ + { 0xAE, 0x52 }, /* REGISTERED SIGN -> 'R' */ + { 0xAF, 0x2D }, /* MACRON -> '-' */ + { 0xB0, 0x6F }, /* DEGREE SIGN -> 'o' */ + { 0xB2, 0x32 }, /* SUPERSCRIPT TWO -> '2' */ + { 0xB3, 0x33 }, /* SUPERSCRIPT THREE -> '3' */ + { 0xB4, 0x27 }, /* ACUTE ACCENT -> ''' */ + { 0xB5, 0x75 }, /* MICRO SIGN -> 'u' */ + { 0xB6, 0x50 }, /* PILCROW SIGN -> 'P' */ + { 0xB7, 0x2A }, /* MIDDLE DOT -> '*' */ + { 0xB8, 0x2C }, /* CEDILLA -> ',' */ + { 0xB9, 0x31 }, /* SUPERSCRIPT ONE -> '1' */ + { 0xBA, 0x6F }, /* MASCULINE ORDINAL INDICATOR -> 'o' */ + { 0xBB, 0x3E }, /* RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK -> '>' */ + { 0xBF, 0x3F }, /* INVERTED QUESTION MARK -> '?' */ + { 0xC0, 0x00 }, /* LATIN CAPITAL LETTER A WITH GRAVE -> ... */ + { 0xC5, 0x41 }, /* LATIN CAPITAL LETTER A WITH RING ABOVE -> 'A' */ + { 0xC6, 0x45 }, /* LATIN CAPITAL LETTER AE -> 'E' */ + { 0xC7, 0x43 }, /* LATIN CAPITAL LETTER C WITH CEDILLA -> 'C' */ + { 0xC8, 0x00 }, /* LATIN CAPITAL LETTER E WITH GRAVE -> ... */ + { 0xCB, 0x45 }, /* LATIN CAPITAL LETTER E WITH DIAERESIS -> 'E' */ + { 0xCC, 0x00 }, /* LATIN CAPITAL LETTER I WITH GRAVE -> ... */ + { 0xCF, 0x49 }, /* LATIN CAPITAL LETTER I WITH DIAERESIS -> 'I' */ + { 0xD0, 0x44 }, /* LATIN CAPITAL LETTER ETH -> 'D' */ + { 0xD1, 0x4E }, /* LATIN CAPITAL LETTER N WITH TILDE -> 'N' */ + { 0xD2, 0x00 }, /* LATIN CAPITAL LETTER O WITH GRAVE -> ... */ + { 0xD6, 0x4F }, /* LATIN CAPITAL LETTER O WITH DIAERESIS -> 'O' */ + { 0xD7, 0x78 }, /* MULTIPLICATION SIGN -> 'x' */ + { 0xD8, 0x4F }, /* LATIN CAPITAL LETTER O WITH STROKE -> 'O' */ + { 0xD9, 0x00 }, /* LATIN CAPITAL LETTER U WITH GRAVE -> ... */ + { 0xDC, 0x55 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS -> 'U' */ + { 0xDD, 0x59 }, /* LATIN CAPITAL LETTER Y WITH ACUTE -> 'Y' */ + { 0xDF, 0x73 }, /* LATIN SMALL LETTER SHARP S -> 's' */ + { 0xE0, 0x00 }, /* LATIN SMALL LETTER A WITH GRAVE -> ... */ + { 0xE5, 0x61 }, /* LATIN SMALL LETTER A WITH RING ABOVE -> 'a' */ + { 0xE6, 0x65 }, /* LATIN SMALL LETTER AE -> 'e' */ + { 0xE7, 0x63 }, /* LATIN SMALL LETTER C WITH CEDILLA -> 'c' */ + { 0xE8, 0x00 }, /* LATIN SMALL LETTER E WITH GRAVE -> ... */ + { 0xEB, 0x65 }, /* LATIN SMALL LETTER E WITH DIAERESIS -> 'e' */ + { 0xEC, 0x00 }, /* LATIN SMALL LETTER I WITH GRAVE -> ... */ + { 0xEF, 0x69 }, /* LATIN SMALL LETTER I WITH DIAERESIS -> 'i' */ + { 0xF0, 0x64 }, /* LATIN SMALL LETTER ETH -> 'd' */ + { 0xF1, 0x6E }, /* LATIN SMALL LETTER N WITH TILDE -> 'n' */ + { 0xF2, 0x00 }, /* LATIN SMALL LETTER O WITH GRAVE -> ... */ + { 0xF6, 0x6F }, /* LATIN SMALL LETTER O WITH DIAERESIS -> 'o' */ + { 0xF7, 0x2F }, /* DIVISION SIGN -> '/' */ + { 0xF8, 0x6F }, /* LATIN SMALL LETTER O WITH STROKE -> 'o' */ + { 0xF9, 0x00 }, /* LATIN SMALL LETTER U WITH GRAVE -> ... */ + { 0xFC, 0x75 }, /* LATIN SMALL LETTER U WITH DIAERESIS -> 'u' */ + { 0xFD, 0x79 }, /* LATIN SMALL LETTER Y WITH ACUTE -> 'y' */ + { 0xFF, 0x79 }, /* LATIN SMALL LETTER Y WITH DIAERESIS -> 'y' */ + /* Entries for page 0x01 */ + { 0x00, 0x41 }, /* LATIN CAPITAL LETTER A WITH MACRON -> 'A' */ + { 0x01, 0x61 }, /* LATIN SMALL LETTER A WITH MACRON -> 'a' */ + { 0x02, 0x41 }, /* LATIN CAPITAL LETTER A WITH BREVE -> 'A' */ + { 0x03, 0x61 }, /* LATIN SMALL LETTER A WITH BREVE -> 'a' */ + { 0x04, 0x41 }, /* LATIN CAPITAL LETTER A WITH OGONEK -> 'A' */ + { 0x05, 0x61 }, /* LATIN SMALL LETTER A WITH OGONEK -> 'a' */ + { 0x06, 0x43 }, /* LATIN CAPITAL LETTER C WITH ACUTE -> 'C' */ + { 0x07, 0x63 }, /* LATIN SMALL LETTER C WITH ACUTE -> 'c' */ + { 0x08, 0x43 }, /* LATIN CAPITAL LETTER C WITH CIRCUMFLEX -> 'C' */ + { 0x09, 0x63 }, /* LATIN SMALL LETTER C WITH CIRCUMFLEX -> 'c' */ + { 0x0A, 0x43 }, /* LATIN CAPITAL LETTER C WITH DOT ABOVE -> 'C' */ + { 0x0B, 0x63 }, /* LATIN SMALL LETTER C WITH DOT ABOVE -> 'c' */ + { 0x0C, 0x43 }, /* LATIN CAPITAL LETTER C WITH CARON -> 'C' */ + { 0x0D, 0x63 }, /* LATIN SMALL LETTER C WITH CARON -> 'c' */ + { 0x0E, 0x44 }, /* LATIN CAPITAL LETTER D WITH CARON -> 'D' */ + { 0x0F, 0x64 }, /* LATIN SMALL LETTER D WITH CARON -> 'd' */ + { 0x10, 0x44 }, /* LATIN CAPITAL LETTER D WITH STROKE -> 'D' */ + { 0x11, 0x64 }, /* LATIN SMALL LETTER D WITH STROKE -> 'd' */ + { 0x12, 0x45 }, /* LATIN CAPITAL LETTER E WITH MACRON -> 'E' */ + { 0x13, 0x65 }, /* LATIN SMALL LETTER E WITH MACRON -> 'e' */ + { 0x14, 0x45 }, /* LATIN CAPITAL LETTER E WITH BREVE -> 'E' */ + { 0x15, 0x65 }, /* LATIN SMALL LETTER E WITH BREVE -> 'e' */ + { 0x16, 0x45 }, /* LATIN CAPITAL LETTER E WITH DOT ABOVE -> 'E' */ + { 0x17, 0x65 }, /* LATIN SMALL LETTER E WITH DOT ABOVE -> 'e' */ + { 0x18, 0x45 }, /* LATIN CAPITAL LETTER E WITH OGONEK -> 'E' */ + { 0x19, 0x65 }, /* LATIN SMALL LETTER E WITH OGONEK -> 'e' */ + { 0x1A, 0x45 }, /* LATIN CAPITAL LETTER E WITH CARON -> 'E' */ + { 0x1B, 0x65 }, /* LATIN SMALL LETTER E WITH CARON -> 'e' */ + { 0x1C, 0x47 }, /* LATIN CAPITAL LETTER G WITH CIRCUMFLEX -> 'G' */ + { 0x1D, 0x67 }, /* LATIN SMALL LETTER G WITH CIRCUMFLEX -> 'g' */ + { 0x1E, 0x47 }, /* LATIN CAPITAL LETTER G WITH BREVE -> 'G' */ + { 0x1F, 0x67 }, /* LATIN SMALL LETTER G WITH BREVE -> 'g' */ + { 0x20, 0x47 }, /* LATIN CAPITAL LETTER G WITH DOT ABOVE -> 'G' */ + { 0x21, 0x67 }, /* LATIN SMALL LETTER G WITH DOT ABOVE -> 'g' */ + { 0x22, 0x47 }, /* LATIN CAPITAL LETTER G WITH CEDILLA -> 'G' */ + { 0x23, 0x67 }, /* LATIN SMALL LETTER G WITH CEDILLA -> 'g' */ + { 0x24, 0x48 }, /* LATIN CAPITAL LETTER H WITH CIRCUMFLEX -> 'H' */ + { 0x25, 0x68 }, /* LATIN SMALL LETTER H WITH CIRCUMFLEX -> 'h' */ + { 0x26, 0x48 }, /* LATIN CAPITAL LETTER H WITH STROKE -> 'H' */ + { 0x27, 0x68 }, /* LATIN SMALL LETTER H WITH STROKE -> 'h' */ + { 0x28, 0x49 }, /* LATIN CAPITAL LETTER I WITH TILDE -> 'I' */ + { 0x29, 0x69 }, /* LATIN SMALL LETTER I WITH TILDE -> 'i' */ + { 0x2A, 0x49 }, /* LATIN CAPITAL LETTER I WITH MACRON -> 'I' */ + { 0x2B, 0x69 }, /* LATIN SMALL LETTER I WITH MACRON -> 'i' */ + { 0x2C, 0x49 }, /* LATIN CAPITAL LETTER I WITH BREVE -> 'I' */ + { 0x2D, 0x69 }, /* LATIN SMALL LETTER I WITH BREVE -> 'i' */ + { 0x2E, 0x49 }, /* LATIN CAPITAL LETTER I WITH OGONEK -> 'I' */ + { 0x2F, 0x69 }, /* LATIN SMALL LETTER I WITH OGONEK -> 'i' */ + { 0x30, 0x49 }, /* LATIN CAPITAL LETTER I WITH DOT ABOVE -> 'I' */ + { 0x31, 0x69 }, /* LATIN SMALL LETTER DOTLESS I -> 'i' */ + { 0x34, 0x4A }, /* LATIN CAPITAL LETTER J WITH CIRCUMFLEX -> 'J' */ + { 0x35, 0x6A }, /* LATIN SMALL LETTER J WITH CIRCUMFLEX -> 'j' */ + { 0x36, 0x4B }, /* LATIN CAPITAL LETTER K WITH CEDILLA -> 'K' */ + { 0x37, 0x6B }, /* LATIN SMALL LETTER K WITH CEDILLA -> 'k' */ + { 0x38, 0x6B }, /* LATIN SMALL LETTER KRA -> 'k' */ + { 0x39, 0x4C }, /* LATIN CAPITAL LETTER L WITH ACUTE -> 'L' */ + { 0x3A, 0x6C }, /* LATIN SMALL LETTER L WITH ACUTE -> 'l' */ + { 0x3B, 0x4C }, /* LATIN CAPITAL LETTER L WITH CEDILLA -> 'L' */ + { 0x3C, 0x6C }, /* LATIN SMALL LETTER L WITH CEDILLA -> 'l' */ + { 0x3D, 0x4C }, /* LATIN CAPITAL LETTER L WITH CARON -> 'L' */ + { 0x3E, 0x6C }, /* LATIN SMALL LETTER L WITH CARON -> 'l' */ + { 0x3F, 0x4C }, /* LATIN CAPITAL LETTER L WITH MIDDLE DOT -> 'L' */ + { 0x40, 0x6C }, /* LATIN SMALL LETTER L WITH MIDDLE DOT -> 'l' */ + { 0x41, 0x4C }, /* LATIN CAPITAL LETTER L WITH STROKE -> 'L' */ + { 0x42, 0x6C }, /* LATIN SMALL LETTER L WITH STROKE -> 'l' */ + { 0x43, 0x4E }, /* LATIN CAPITAL LETTER N WITH ACUTE -> 'N' */ + { 0x44, 0x6E }, /* LATIN SMALL LETTER N WITH ACUTE -> 'n' */ + { 0x45, 0x4E }, /* LATIN CAPITAL LETTER N WITH CEDILLA -> 'N' */ + { 0x46, 0x6E }, /* LATIN SMALL LETTER N WITH CEDILLA -> 'n' */ + { 0x47, 0x4E }, /* LATIN CAPITAL LETTER N WITH CARON -> 'N' */ + { 0x48, 0x6E }, /* LATIN SMALL LETTER N WITH CARON -> 'n' */ + { 0x4C, 0x4F }, /* LATIN CAPITAL LETTER O WITH MACRON -> 'O' */ + { 0x4D, 0x6F }, /* LATIN SMALL LETTER O WITH MACRON -> 'o' */ + { 0x4E, 0x4F }, /* LATIN CAPITAL LETTER O WITH BREVE -> 'O' */ + { 0x4F, 0x6F }, /* LATIN SMALL LETTER O WITH BREVE -> 'o' */ + { 0x50, 0x4F }, /* LATIN CAPITAL LETTER O WITH DOUBLE ACUTE -> 'O' */ + { 0x51, 0x6F }, /* LATIN SMALL LETTER O WITH DOUBLE ACUTE -> 'o' */ + { 0x52, 0x45 }, /* LATIN CAPITAL LIGATURE OE -> 'E' */ + { 0x53, 0x65 }, /* LATIN SMALL LIGATURE OE -> 'e' */ + { 0x54, 0x52 }, /* LATIN CAPITAL LETTER R WITH ACUTE -> 'R' */ + { 0x55, 0x72 }, /* LATIN SMALL LETTER R WITH ACUTE -> 'r' */ + { 0x56, 0x52 }, /* LATIN CAPITAL LETTER R WITH CEDILLA -> 'R' */ + { 0x57, 0x72 }, /* LATIN SMALL LETTER R WITH CEDILLA -> 'r' */ + { 0x58, 0x52 }, /* LATIN CAPITAL LETTER R WITH CARON -> 'R' */ + { 0x59, 0x72 }, /* LATIN SMALL LETTER R WITH CARON -> 'r' */ + { 0x5A, 0x53 }, /* LATIN CAPITAL LETTER S WITH ACUTE -> 'S' */ + { 0x5B, 0x73 }, /* LATIN SMALL LETTER S WITH ACUTE -> 's' */ + { 0x5C, 0x53 }, /* LATIN CAPITAL LETTER S WITH CIRCUMFLEX -> 'S' */ + { 0x5D, 0x73 }, /* LATIN SMALL LETTER S WITH CIRCUMFLEX -> 's' */ + { 0x5E, 0x53 }, /* LATIN CAPITAL LETTER S WITH CEDILLA -> 'S' */ + { 0x5F, 0x73 }, /* LATIN SMALL LETTER S WITH CEDILLA -> 's' */ + { 0x60, 0x53 }, /* LATIN CAPITAL LETTER S WITH CARON -> 'S' */ + { 0x61, 0x73 }, /* LATIN SMALL LETTER S WITH CARON -> 's' */ + { 0x62, 0x54 }, /* LATIN CAPITAL LETTER T WITH CEDILLA -> 'T' */ + { 0x63, 0x74 }, /* LATIN SMALL LETTER T WITH CEDILLA -> 't' */ + { 0x64, 0x54 }, /* LATIN CAPITAL LETTER T WITH CARON -> 'T' */ + { 0x65, 0x74 }, /* LATIN SMALL LETTER T WITH CARON -> 't' */ + { 0x66, 0x54 }, /* LATIN CAPITAL LETTER T WITH STROKE -> 'T' */ + { 0x67, 0x74 }, /* LATIN SMALL LETTER T WITH STROKE -> 't' */ + { 0x68, 0x55 }, /* LATIN CAPITAL LETTER U WITH TILDE -> 'U' */ + { 0x69, 0x75 }, /* LATIN SMALL LETTER U WITH TILDE -> 'u' */ + { 0x6A, 0x55 }, /* LATIN CAPITAL LETTER U WITH MACRON -> 'U' */ + { 0x6B, 0x75 }, /* LATIN SMALL LETTER U WITH MACRON -> 'u' */ + { 0x6C, 0x55 }, /* LATIN CAPITAL LETTER U WITH BREVE -> 'U' */ + { 0x6D, 0x75 }, /* LATIN SMALL LETTER U WITH BREVE -> 'u' */ + { 0x6E, 0x55 }, /* LATIN CAPITAL LETTER U WITH RING ABOVE -> 'U' */ + { 0x6F, 0x75 }, /* LATIN SMALL LETTER U WITH RING ABOVE -> 'u' */ + { 0x70, 0x55 }, /* LATIN CAPITAL LETTER U WITH DOUBLE ACUTE -> 'U' */ + { 0x71, 0x75 }, /* LATIN SMALL LETTER U WITH DOUBLE ACUTE -> 'u' */ + { 0x72, 0x55 }, /* LATIN CAPITAL LETTER U WITH OGONEK -> 'U' */ + { 0x73, 0x75 }, /* LATIN SMALL LETTER U WITH OGONEK -> 'u' */ + { 0x74, 0x57 }, /* LATIN CAPITAL LETTER W WITH CIRCUMFLEX -> 'W' */ + { 0x75, 0x77 }, /* LATIN SMALL LETTER W WITH CIRCUMFLEX -> 'w' */ + { 0x76, 0x59 }, /* LATIN CAPITAL LETTER Y WITH CIRCUMFLEX -> 'Y' */ + { 0x77, 0x79 }, /* LATIN SMALL LETTER Y WITH CIRCUMFLEX -> 'y' */ + { 0x78, 0x59 }, /* LATIN CAPITAL LETTER Y WITH DIAERESIS -> 'Y' */ + { 0x79, 0x5A }, /* LATIN CAPITAL LETTER Z WITH ACUTE -> 'Z' */ + { 0x7A, 0x7A }, /* LATIN SMALL LETTER Z WITH ACUTE -> 'z' */ + { 0x7B, 0x5A }, /* LATIN CAPITAL LETTER Z WITH DOT ABOVE -> 'Z' */ + { 0x7C, 0x7A }, /* LATIN SMALL LETTER Z WITH DOT ABOVE -> 'z' */ + { 0x7D, 0x5A }, /* LATIN CAPITAL LETTER Z WITH CARON -> 'Z' */ + { 0x7E, 0x7A }, /* LATIN SMALL LETTER Z WITH CARON -> 'z' */ + { 0x7F, 0x73 }, /* LATIN SMALL LETTER LONG S -> 's' */ + { 0x80, 0x62 }, /* LATIN SMALL LETTER B WITH STROKE -> 'b' */ + { 0x81, 0x42 }, /* LATIN CAPITAL LETTER B WITH HOOK -> 'B' */ + { 0x82, 0x42 }, /* LATIN CAPITAL LETTER B WITH TOPBAR -> 'B' */ + { 0x83, 0x62 }, /* LATIN SMALL LETTER B WITH TOPBAR -> 'b' */ + { 0x84, 0x36 }, /* LATIN CAPITAL LETTER TONE SIX -> '6' */ + { 0x85, 0x36 }, /* LATIN SMALL LETTER TONE SIX -> '6' */ + { 0x86, 0x4F }, /* LATIN CAPITAL LETTER OPEN O -> 'O' */ + { 0x87, 0x43 }, /* LATIN CAPITAL LETTER C WITH HOOK -> 'C' */ + { 0x88, 0x63 }, /* LATIN SMALL LETTER C WITH HOOK -> 'c' */ + { 0x89, 0x00 }, /* LATIN CAPITAL LETTER AFRICAN D -> ... */ + { 0x8B, 0x44 }, /* LATIN CAPITAL LETTER D WITH TOPBAR -> 'D' */ + { 0x8C, 0x64 }, /* LATIN SMALL LETTER D WITH TOPBAR -> 'd' */ + { 0x8D, 0x64 }, /* LATIN SMALL LETTER TURNED DELTA -> 'd' */ + { 0x8E, 0x33 }, /* LATIN CAPITAL LETTER REVERSED E -> '3' */ + { 0x8F, 0x40 }, /* LATIN CAPITAL LETTER SCHWA -> '@' */ + { 0x90, 0x45 }, /* LATIN CAPITAL LETTER OPEN E -> 'E' */ + { 0x91, 0x46 }, /* LATIN CAPITAL LETTER F WITH HOOK -> 'F' */ + { 0x92, 0x66 }, /* LATIN SMALL LETTER F WITH HOOK -> 'f' */ + { 0x93, 0x47 }, /* LATIN CAPITAL LETTER G WITH HOOK -> 'G' */ + { 0x94, 0x47 }, /* LATIN CAPITAL LETTER GAMMA -> 'G' */ + { 0x96, 0x49 }, /* LATIN CAPITAL LETTER IOTA -> 'I' */ + { 0x97, 0x49 }, /* LATIN CAPITAL LETTER I WITH STROKE -> 'I' */ + { 0x98, 0x4B }, /* LATIN CAPITAL LETTER K WITH HOOK -> 'K' */ + { 0x99, 0x6B }, /* LATIN SMALL LETTER K WITH HOOK -> 'k' */ + { 0x9A, 0x6C }, /* LATIN SMALL LETTER L WITH BAR -> 'l' */ + { 0x9B, 0x6C }, /* LATIN SMALL LETTER LAMBDA WITH STROKE -> 'l' */ + { 0x9C, 0x57 }, /* LATIN CAPITAL LETTER TURNED M -> 'W' */ + { 0x9D, 0x4E }, /* LATIN CAPITAL LETTER N WITH LEFT HOOK -> 'N' */ + { 0x9E, 0x6E }, /* LATIN SMALL LETTER N WITH LONG RIGHT LEG -> 'n' */ + { 0x9F, 0x4F }, /* LATIN CAPITAL LETTER O WITH MIDDLE TILDE -> 'O' */ + { 0xA0, 0x4F }, /* LATIN CAPITAL LETTER O WITH HORN -> 'O' */ + { 0xA1, 0x6F }, /* LATIN SMALL LETTER O WITH HORN -> 'o' */ + { 0xA4, 0x50 }, /* LATIN CAPITAL LETTER P WITH HOOK -> 'P' */ + { 0xA5, 0x70 }, /* LATIN SMALL LETTER P WITH HOOK -> 'p' */ + { 0xA7, 0x32 }, /* LATIN CAPITAL LETTER TONE TWO -> '2' */ + { 0xA8, 0x32 }, /* LATIN SMALL LETTER TONE TWO -> '2' */ + { 0xAB, 0x74 }, /* LATIN SMALL LETTER T WITH PALATAL HOOK -> 't' */ + { 0xAC, 0x54 }, /* LATIN CAPITAL LETTER T WITH HOOK -> 'T' */ + { 0xAD, 0x74 }, /* LATIN SMALL LETTER T WITH HOOK -> 't' */ + { 0xAE, 0x54 }, /* LATIN CAPITAL LETTER T WITH RETROFLEX HOOK -> 'T' */ + { 0xAF, 0x55 }, /* LATIN CAPITAL LETTER U WITH HORN -> 'U' */ + { 0xB0, 0x75 }, /* LATIN SMALL LETTER U WITH HORN -> 'u' */ + { 0xB1, 0x59 }, /* LATIN CAPITAL LETTER UPSILON -> 'Y' */ + { 0xB2, 0x56 }, /* LATIN CAPITAL LETTER V WITH HOOK -> 'V' */ + { 0xB3, 0x59 }, /* LATIN CAPITAL LETTER Y WITH HOOK -> 'Y' */ + { 0xB4, 0x79 }, /* LATIN SMALL LETTER Y WITH HOOK -> 'y' */ + { 0xB5, 0x5A }, /* LATIN CAPITAL LETTER Z WITH STROKE -> 'Z' */ + { 0xB6, 0x7A }, /* LATIN SMALL LETTER Z WITH STROKE -> 'z' */ + { 0xBB, 0x32 }, /* LATIN LETTER TWO WITH STROKE -> '2' */ + { 0xBC, 0x35 }, /* LATIN CAPITAL LETTER TONE FIVE -> '5' */ + { 0xBD, 0x35 }, /* LATIN SMALL LETTER TONE FIVE -> '5' */ + { 0xBF, 0x77 }, /* LATIN LETTER WYNN -> 'w' */ + { 0xC0, 0x7C }, /* LATIN LETTER DENTAL CLICK -> '|' */ + { 0xC3, 0x21 }, /* LATIN LETTER RETROFLEX CLICK -> '!' */ + { 0xCD, 0x41 }, /* LATIN CAPITAL LETTER A WITH CARON -> 'A' */ + { 0xCE, 0x61 }, /* LATIN SMALL LETTER A WITH CARON -> 'a' */ + { 0xCF, 0x49 }, /* LATIN CAPITAL LETTER I WITH CARON -> 'I' */ + { 0xD0, 0x69 }, /* LATIN SMALL LETTER I WITH CARON -> 'i' */ + { 0xD1, 0x4F }, /* LATIN CAPITAL LETTER O WITH CARON -> 'O' */ + { 0xD2, 0x6F }, /* LATIN SMALL LETTER O WITH CARON -> 'o' */ + { 0xD3, 0x55 }, /* LATIN CAPITAL LETTER U WITH CARON -> 'U' */ + { 0xD4, 0x75 }, /* LATIN SMALL LETTER U WITH CARON -> 'u' */ + { 0xD5, 0x55 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON -> 'U' */ + { 0xD6, 0x75 }, /* LATIN SMALL LETTER U WITH DIAERESIS AND MACRON -> 'u' */ + { 0xD7, 0x55 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE -> 'U' */ + { 0xD8, 0x75 }, /* LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE -> 'u' */ + { 0xD9, 0x55 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON -> 'U' */ + { 0xDA, 0x75 }, /* LATIN SMALL LETTER U WITH DIAERESIS AND CARON -> 'u' */ + { 0xDB, 0x55 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE -> 'U' */ + { 0xDC, 0x75 }, /* LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE -> 'u' */ + { 0xDD, 0x40 }, /* LATIN SMALL LETTER TURNED E -> '@' */ + { 0xDE, 0x41 }, /* LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON -> 'A' */ + { 0xDF, 0x61 }, /* LATIN SMALL LETTER A WITH DIAERESIS AND MACRON -> 'a' */ + { 0xE0, 0x41 }, /* LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON -> 'A' */ + { 0xE1, 0x61 }, /* LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON -> 'a' */ + { 0xE4, 0x47 }, /* LATIN CAPITAL LETTER G WITH STROKE -> 'G' */ + { 0xE5, 0x67 }, /* LATIN SMALL LETTER G WITH STROKE -> 'g' */ + { 0xE6, 0x47 }, /* LATIN CAPITAL LETTER G WITH CARON -> 'G' */ + { 0xE7, 0x67 }, /* LATIN SMALL LETTER G WITH CARON -> 'g' */ + { 0xE8, 0x4B }, /* LATIN CAPITAL LETTER K WITH CARON -> 'K' */ + { 0xE9, 0x6B }, /* LATIN SMALL LETTER K WITH CARON -> 'k' */ + { 0xEA, 0x4F }, /* LATIN CAPITAL LETTER O WITH OGONEK -> 'O' */ + { 0xEB, 0x6F }, /* LATIN SMALL LETTER O WITH OGONEK -> 'o' */ + { 0xEC, 0x4F }, /* LATIN CAPITAL LETTER O WITH OGONEK AND MACRON -> 'O' */ + { 0xED, 0x6F }, /* LATIN SMALL LETTER O WITH OGONEK AND MACRON -> 'o' */ + { 0xF0, 0x6A }, /* LATIN SMALL LETTER J WITH CARON -> 'j' */ + { 0xF4, 0x47 }, /* LATIN CAPITAL LETTER G WITH ACUTE -> 'G' */ + { 0xF5, 0x67 }, /* LATIN SMALL LETTER G WITH ACUTE -> 'g' */ + { 0xF7, 0x57 }, /* LATIN CAPITAL LETTER WYNN -> 'W' */ + { 0xF8, 0x4E }, /* LATIN CAPITAL LETTER N WITH GRAVE -> 'N' */ + { 0xF9, 0x6E }, /* LATIN SMALL LETTER N WITH GRAVE -> 'n' */ + { 0xFA, 0x41 }, /* LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE -> 'A' */ + { 0xFB, 0x61 }, /* LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE -> 'a' */ + { 0xFE, 0x4F }, /* LATIN CAPITAL LETTER O WITH STROKE AND ACUTE -> 'O' */ + { 0xFF, 0x6F }, /* LATIN SMALL LETTER O WITH STROKE AND ACUTE -> 'o' */ + /* Entries for page 0x02 */ + { 0x00, 0x41 }, /* LATIN CAPITAL LETTER A WITH DOUBLE GRAVE -> 'A' */ + { 0x01, 0x61 }, /* LATIN SMALL LETTER A WITH DOUBLE GRAVE -> 'a' */ + { 0x02, 0x41 }, /* LATIN CAPITAL LETTER A WITH INVERTED BREVE -> 'A' */ + { 0x03, 0x61 }, /* LATIN SMALL LETTER A WITH INVERTED BREVE -> 'a' */ + { 0x04, 0x45 }, /* LATIN CAPITAL LETTER E WITH DOUBLE GRAVE -> 'E' */ + { 0x05, 0x65 }, /* LATIN SMALL LETTER E WITH DOUBLE GRAVE -> 'e' */ + { 0x06, 0x45 }, /* LATIN CAPITAL LETTER E WITH INVERTED BREVE -> 'E' */ + { 0x07, 0x65 }, /* LATIN SMALL LETTER E WITH INVERTED BREVE -> 'e' */ + { 0x08, 0x49 }, /* LATIN CAPITAL LETTER I WITH DOUBLE GRAVE -> 'I' */ + { 0x09, 0x69 }, /* LATIN SMALL LETTER I WITH DOUBLE GRAVE -> 'i' */ + { 0x0A, 0x49 }, /* LATIN CAPITAL LETTER I WITH INVERTED BREVE -> 'I' */ + { 0x0B, 0x69 }, /* LATIN SMALL LETTER I WITH INVERTED BREVE -> 'i' */ + { 0x0C, 0x4F }, /* LATIN CAPITAL LETTER O WITH DOUBLE GRAVE -> 'O' */ + { 0x0D, 0x6F }, /* LATIN SMALL LETTER O WITH DOUBLE GRAVE -> 'o' */ + { 0x0E, 0x4F }, /* LATIN CAPITAL LETTER O WITH INVERTED BREVE -> 'O' */ + { 0x0F, 0x6F }, /* LATIN SMALL LETTER O WITH INVERTED BREVE -> 'o' */ + { 0x10, 0x52 }, /* LATIN CAPITAL LETTER R WITH DOUBLE GRAVE -> 'R' */ + { 0x11, 0x72 }, /* LATIN SMALL LETTER R WITH DOUBLE GRAVE -> 'r' */ + { 0x12, 0x52 }, /* LATIN CAPITAL LETTER R WITH INVERTED BREVE -> 'R' */ + { 0x13, 0x72 }, /* LATIN SMALL LETTER R WITH INVERTED BREVE -> 'r' */ + { 0x14, 0x55 }, /* LATIN CAPITAL LETTER U WITH DOUBLE GRAVE -> 'U' */ + { 0x15, 0x75 }, /* LATIN SMALL LETTER U WITH DOUBLE GRAVE -> 'u' */ + { 0x16, 0x55 }, /* LATIN CAPITAL LETTER U WITH INVERTED BREVE -> 'U' */ + { 0x17, 0x75 }, /* LATIN SMALL LETTER U WITH INVERTED BREVE -> 'u' */ + { 0x18, 0x53 }, /* LATIN CAPITAL LETTER S WITH COMMA BELOW -> 'S' */ + { 0x19, 0x73 }, /* LATIN SMALL LETTER S WITH COMMA BELOW -> 's' */ + { 0x1A, 0x54 }, /* LATIN CAPITAL LETTER T WITH COMMA BELOW -> 'T' */ + { 0x1B, 0x74 }, /* LATIN SMALL LETTER T WITH COMMA BELOW -> 't' */ + { 0x1C, 0x59 }, /* LATIN CAPITAL LETTER YOGH -> 'Y' */ + { 0x1D, 0x79 }, /* LATIN SMALL LETTER YOGH -> 'y' */ + { 0x1E, 0x48 }, /* LATIN CAPITAL LETTER H WITH CARON -> 'H' */ + { 0x1F, 0x68 }, /* LATIN SMALL LETTER H WITH CARON -> 'h' */ + { 0x20, 0x4E }, /* LATIN CAPITAL LETTER N WITH LONG RIGHT LEG -> 'N' */ + { 0x21, 0x64 }, /* LATIN SMALL LETTER D WITH CURL -> 'd' */ + { 0x24, 0x5A }, /* LATIN CAPITAL LETTER Z WITH HOOK -> 'Z' */ + { 0x25, 0x7A }, /* LATIN SMALL LETTER Z WITH HOOK -> 'z' */ + { 0x26, 0x41 }, /* LATIN CAPITAL LETTER A WITH DOT ABOVE -> 'A' */ + { 0x27, 0x61 }, /* LATIN SMALL LETTER A WITH DOT ABOVE -> 'a' */ + { 0x28, 0x45 }, /* LATIN CAPITAL LETTER E WITH CEDILLA -> 'E' */ + { 0x29, 0x65 }, /* LATIN SMALL LETTER E WITH CEDILLA -> 'e' */ + { 0x2A, 0x4F }, /* LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON -> 'O' */ + { 0x2B, 0x6F }, /* LATIN SMALL LETTER O WITH DIAERESIS AND MACRON -> 'o' */ + { 0x2C, 0x4F }, /* LATIN CAPITAL LETTER O WITH TILDE AND MACRON -> 'O' */ + { 0x2D, 0x6F }, /* LATIN SMALL LETTER O WITH TILDE AND MACRON -> 'o' */ + { 0x2E, 0x4F }, /* LATIN CAPITAL LETTER O WITH DOT ABOVE -> 'O' */ + { 0x2F, 0x6F }, /* LATIN SMALL LETTER O WITH DOT ABOVE -> 'o' */ + { 0x30, 0x4F }, /* LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON -> 'O' */ + { 0x31, 0x6F }, /* LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON -> 'o' */ + { 0x32, 0x59 }, /* LATIN CAPITAL LETTER Y WITH MACRON -> 'Y' */ + { 0x33, 0x79 }, /* LATIN SMALL LETTER Y WITH MACRON -> 'y' */ + { 0x34, 0x6C }, /* LATIN SMALL LETTER L WITH CURL -> 'l' */ + { 0x35, 0x6E }, /* LATIN SMALL LETTER N WITH CURL -> 'n' */ + { 0x36, 0x74 }, /* LATIN SMALL LETTER T WITH CURL -> 't' */ + { 0x37, 0x6A }, /* LATIN SMALL LETTER DOTLESS J -> 'j' */ + { 0x3A, 0x41 }, /* LATIN CAPITAL LETTER A WITH STROKE -> 'A' */ + { 0x3B, 0x43 }, /* LATIN CAPITAL LETTER C WITH STROKE -> 'C' */ + { 0x3C, 0x63 }, /* LATIN SMALL LETTER C WITH STROKE -> 'c' */ + { 0x3D, 0x4C }, /* LATIN CAPITAL LETTER L WITH BAR -> 'L' */ + { 0x3E, 0x54 }, /* LATIN CAPITAL LETTER T WITH DIAGONAL STROKE -> 'T' */ + { 0x3F, 0x73 }, /* LATIN SMALL LETTER S WITH SWASH TAIL -> 's' */ + { 0x40, 0x7A }, /* LATIN SMALL LETTER Z WITH SWASH TAIL -> 'z' */ + { 0x43, 0x42 }, /* LATIN CAPITAL LETTER B WITH STROKE -> 'B' */ + { 0x44, 0x55 }, /* LATIN CAPITAL LETTER U BAR -> 'U' */ + { 0x45, 0x5E }, /* LATIN CAPITAL LETTER TURNED V -> '^' */ + { 0x46, 0x45 }, /* LATIN CAPITAL LETTER E WITH STROKE -> 'E' */ + { 0x47, 0x65 }, /* LATIN SMALL LETTER E WITH STROKE -> 'e' */ + { 0x48, 0x4A }, /* LATIN CAPITAL LETTER J WITH STROKE -> 'J' */ + { 0x49, 0x6A }, /* LATIN SMALL LETTER J WITH STROKE -> 'j' */ + { 0x4A, 0x71 }, /* LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL -> 'q' */ + { 0x4B, 0x71 }, /* LATIN SMALL LETTER Q WITH HOOK TAIL -> 'q' */ + { 0x4C, 0x52 }, /* LATIN CAPITAL LETTER R WITH STROKE -> 'R' */ + { 0x4D, 0x72 }, /* LATIN SMALL LETTER R WITH STROKE -> 'r' */ + { 0x4E, 0x59 }, /* LATIN CAPITAL LETTER Y WITH STROKE -> 'Y' */ + { 0x4F, 0x79 }, /* LATIN SMALL LETTER Y WITH STROKE -> 'y' */ + { 0x50, 0x00 }, /* LATIN SMALL LETTER TURNED A -> ... */ + { 0x52, 0x61 }, /* LATIN SMALL LETTER TURNED ALPHA -> 'a' */ + { 0x53, 0x62 }, /* LATIN SMALL LETTER B WITH HOOK -> 'b' */ + { 0x54, 0x6F }, /* LATIN SMALL LETTER OPEN O -> 'o' */ + { 0x55, 0x63 }, /* LATIN SMALL LETTER C WITH CURL -> 'c' */ + { 0x56, 0x64 }, /* LATIN SMALL LETTER D WITH TAIL -> 'd' */ + { 0x57, 0x64 }, /* LATIN SMALL LETTER D WITH HOOK -> 'd' */ + { 0x58, 0x65 }, /* LATIN SMALL LETTER REVERSED E -> 'e' */ + { 0x59, 0x40 }, /* LATIN SMALL LETTER SCHWA -> '@' */ + { 0x5A, 0x40 }, /* LATIN SMALL LETTER SCHWA WITH HOOK -> '@' */ + { 0x5B, 0x00 }, /* LATIN SMALL LETTER OPEN E -> ... */ + { 0x5E, 0x65 }, /* LATIN SMALL LETTER CLOSED REVERSED OPEN E -> 'e' */ + { 0x5F, 0x6A }, /* LATIN SMALL LETTER DOTLESS J WITH STROKE -> 'j' */ + { 0x60, 0x00 }, /* LATIN SMALL LETTER G WITH HOOK -> ... */ + { 0x63, 0x67 }, /* LATIN SMALL LETTER GAMMA -> 'g' */ + { 0x64, 0x75 }, /* LATIN SMALL LETTER RAMS HORN -> 'u' */ + { 0x65, 0x59 }, /* LATIN SMALL LETTER TURNED H -> 'Y' */ + { 0x66, 0x68 }, /* LATIN SMALL LETTER H WITH HOOK -> 'h' */ + { 0x67, 0x68 }, /* LATIN SMALL LETTER HENG WITH HOOK -> 'h' */ + { 0x68, 0x69 }, /* LATIN SMALL LETTER I WITH STROKE -> 'i' */ + { 0x69, 0x69 }, /* LATIN SMALL LETTER IOTA -> 'i' */ + { 0x6A, 0x49 }, /* LATIN LETTER SMALL CAPITAL I -> 'I' */ + { 0x6B, 0x00 }, /* LATIN SMALL LETTER L WITH MIDDLE TILDE -> ... */ + { 0x6D, 0x6C }, /* LATIN SMALL LETTER L WITH RETROFLEX HOOK -> 'l' */ + { 0x6F, 0x57 }, /* LATIN SMALL LETTER TURNED M -> 'W' */ + { 0x70, 0x57 }, /* LATIN SMALL LETTER TURNED M WITH LONG LEG -> 'W' */ + { 0x71, 0x6D }, /* LATIN SMALL LETTER M WITH HOOK -> 'm' */ + { 0x72, 0x00 }, /* LATIN SMALL LETTER N WITH LEFT HOOK -> ... */ + { 0x74, 0x6E }, /* LATIN LETTER SMALL CAPITAL N -> 'n' */ + { 0x75, 0x6F }, /* LATIN SMALL LETTER BARRED O -> 'o' */ + { 0x77, 0x4F }, /* LATIN SMALL LETTER CLOSED OMEGA -> 'O' */ + { 0x78, 0x46 }, /* LATIN SMALL LETTER PHI -> 'F' */ + { 0x79, 0x00 }, /* LATIN SMALL LETTER TURNED R -> ... */ + { 0x7F, 0x72 }, /* LATIN SMALL LETTER REVERSED R WITH FISHHOOK -> 'r' */ + { 0x80, 0x52 }, /* LATIN LETTER SMALL CAPITAL R -> 'R' */ + { 0x81, 0x52 }, /* LATIN LETTER SMALL CAPITAL INVERTED R -> 'R' */ + { 0x82, 0x73 }, /* LATIN SMALL LETTER S WITH HOOK -> 's' */ + { 0x83, 0x53 }, /* LATIN SMALL LETTER ESH -> 'S' */ + { 0x84, 0x6A }, /* LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK -> 'j' */ + { 0x85, 0x53 }, /* LATIN SMALL LETTER SQUAT REVERSED ESH -> 'S' */ + { 0x86, 0x53 }, /* LATIN SMALL LETTER ESH WITH CURL -> 'S' */ + { 0x87, 0x74 }, /* LATIN SMALL LETTER TURNED T -> 't' */ + { 0x88, 0x74 }, /* LATIN SMALL LETTER T WITH RETROFLEX HOOK -> 't' */ + { 0x89, 0x75 }, /* LATIN SMALL LETTER U BAR -> 'u' */ + { 0x8A, 0x55 }, /* LATIN SMALL LETTER UPSILON -> 'U' */ + { 0x8B, 0x76 }, /* LATIN SMALL LETTER V WITH HOOK -> 'v' */ + { 0x8C, 0x5E }, /* LATIN SMALL LETTER TURNED V -> '^' */ + { 0x8D, 0x77 }, /* LATIN SMALL LETTER TURNED W -> 'w' */ + { 0x8E, 0x79 }, /* LATIN SMALL LETTER TURNED Y -> 'y' */ + { 0x8F, 0x59 }, /* LATIN LETTER SMALL CAPITAL Y -> 'Y' */ + { 0x90, 0x7A }, /* LATIN SMALL LETTER Z WITH RETROFLEX HOOK -> 'z' */ + { 0x91, 0x7A }, /* LATIN SMALL LETTER Z WITH CURL -> 'z' */ + { 0x92, 0x5A }, /* LATIN SMALL LETTER EZH -> 'Z' */ + { 0x93, 0x5A }, /* LATIN SMALL LETTER EZH WITH CURL -> 'Z' */ + { 0x94, 0x00 }, /* LATIN LETTER GLOTTAL STOP -> ... */ + { 0x96, 0x3F }, /* LATIN LETTER INVERTED GLOTTAL STOP -> '?' */ + { 0x97, 0x43 }, /* LATIN LETTER STRETCHED C -> 'C' */ + { 0x98, 0x40 }, /* LATIN LETTER BILABIAL CLICK -> '@' */ + { 0x99, 0x42 }, /* LATIN LETTER SMALL CAPITAL B -> 'B' */ + { 0x9A, 0x45 }, /* LATIN SMALL LETTER CLOSED OPEN E -> 'E' */ + { 0x9B, 0x47 }, /* LATIN LETTER SMALL CAPITAL G WITH HOOK -> 'G' */ + { 0x9C, 0x48 }, /* LATIN LETTER SMALL CAPITAL H -> 'H' */ + { 0x9D, 0x6A }, /* LATIN SMALL LETTER J WITH CROSSED-TAIL -> 'j' */ + { 0x9E, 0x6B }, /* LATIN SMALL LETTER TURNED K -> 'k' */ + { 0x9F, 0x4C }, /* LATIN LETTER SMALL CAPITAL L -> 'L' */ + { 0xA0, 0x71 }, /* LATIN SMALL LETTER Q WITH HOOK -> 'q' */ + { 0xA1, 0x3F }, /* LATIN LETTER GLOTTAL STOP WITH STROKE -> '?' */ + { 0xA2, 0x3F }, /* LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE -> '?' */ + { 0xAE, 0x00 }, /* LATIN SMALL LETTER TURNED H WITH FISHHOOK -> ... */ + { 0xB1, 0x68 }, /* MODIFIER LETTER SMALL H WITH HOOK -> 'h' */ + { 0xB2, 0x6A }, /* MODIFIER LETTER SMALL J -> 'j' */ + { 0xB3, 0x00 }, /* MODIFIER LETTER SMALL R -> ... */ + { 0xB6, 0x72 }, /* MODIFIER LETTER SMALL CAPITAL INVERTED R -> 'r' */ + { 0xB7, 0x77 }, /* MODIFIER LETTER SMALL W -> 'w' */ + { 0xB8, 0x79 }, /* MODIFIER LETTER SMALL Y -> 'y' */ + { 0xB9, 0x27 }, /* MODIFIER LETTER PRIME -> ''' */ + { 0xBA, 0x22 }, /* MODIFIER LETTER DOUBLE PRIME -> '"' */ + { 0xBB, 0x60 }, /* MODIFIER LETTER TURNED COMMA -> '`' */ + { 0xBC, 0x27 }, /* MODIFIER LETTER APOSTROPHE -> ''' */ + { 0xBD, 0x60 }, /* MODIFIER LETTER REVERSED COMMA -> '`' */ + { 0xBE, 0x60 }, /* MODIFIER LETTER RIGHT HALF RING -> '`' */ + { 0xBF, 0x27 }, /* MODIFIER LETTER LEFT HALF RING -> ''' */ + { 0xC0, 0x3F }, /* MODIFIER LETTER GLOTTAL STOP -> '?' */ + { 0xC1, 0x3F }, /* MODIFIER LETTER REVERSED GLOTTAL STOP -> '?' */ + { 0xC2, 0x3C }, /* MODIFIER LETTER LEFT ARROWHEAD -> '<' */ + { 0xC3, 0x3E }, /* MODIFIER LETTER RIGHT ARROWHEAD -> '>' */ + { 0xC4, 0x5E }, /* MODIFIER LETTER UP ARROWHEAD -> '^' */ + { 0xC5, 0x56 }, /* MODIFIER LETTER DOWN ARROWHEAD -> 'V' */ + { 0xC6, 0x5E }, /* MODIFIER LETTER CIRCUMFLEX ACCENT -> '^' */ + { 0xC7, 0x56 }, /* CARON -> 'V' */ + { 0xC8, 0x27 }, /* MODIFIER LETTER VERTICAL LINE -> ''' */ + { 0xC9, 0x2D }, /* MODIFIER LETTER MACRON -> '-' */ + { 0xCA, 0x2F }, /* MODIFIER LETTER ACUTE ACCENT -> '/' */ + { 0xCB, 0x5C }, /* MODIFIER LETTER GRAVE ACCENT -> '\' */ + { 0xCC, 0x2C }, /* MODIFIER LETTER LOW VERTICAL LINE -> ',' */ + { 0xCD, 0x5F }, /* MODIFIER LETTER LOW MACRON -> '_' */ + { 0xCE, 0x5C }, /* MODIFIER LETTER LOW GRAVE ACCENT -> '\' */ + { 0xCF, 0x2F }, /* MODIFIER LETTER LOW ACUTE ACCENT -> '/' */ + { 0xD0, 0x3A }, /* MODIFIER LETTER TRIANGULAR COLON -> ':' */ + { 0xD1, 0x2E }, /* MODIFIER LETTER HALF TRIANGULAR COLON -> '.' */ + { 0xD2, 0x60 }, /* MODIFIER LETTER CENTRED RIGHT HALF RING -> '`' */ + { 0xD3, 0x27 }, /* MODIFIER LETTER CENTRED LEFT HALF RING -> ''' */ + { 0xD4, 0x5E }, /* MODIFIER LETTER UP TACK -> '^' */ + { 0xD5, 0x56 }, /* MODIFIER LETTER DOWN TACK -> 'V' */ + { 0xD6, 0x2B }, /* MODIFIER LETTER PLUS SIGN -> '+' */ + { 0xD7, 0x2D }, /* MODIFIER LETTER MINUS SIGN -> '-' */ + { 0xD8, 0x56 }, /* BREVE -> 'V' */ + { 0xD9, 0x2E }, /* DOT ABOVE -> '.' */ + { 0xDA, 0x40 }, /* RING ABOVE -> '@' */ + { 0xDB, 0x2C }, /* OGONEK -> ',' */ + { 0xDC, 0x7E }, /* SMALL TILDE -> '~' */ + { 0xDD, 0x22 }, /* DOUBLE ACUTE ACCENT -> '"' */ + { 0xDE, 0x52 }, /* MODIFIER LETTER RHOTIC HOOK -> 'R' */ + { 0xDF, 0x58 }, /* MODIFIER LETTER CROSS ACCENT -> 'X' */ + { 0xE0, 0x47 }, /* MODIFIER LETTER SMALL GAMMA -> 'G' */ + { 0xE1, 0x6C }, /* MODIFIER LETTER SMALL L -> 'l' */ + { 0xE2, 0x73 }, /* MODIFIER LETTER SMALL S -> 's' */ + { 0xE3, 0x78 }, /* MODIFIER LETTER SMALL X -> 'x' */ + { 0xE4, 0x3F }, /* MODIFIER LETTER SMALL REVERSED GLOTTAL STOP -> '?' */ + { 0xEC, 0x56 }, /* MODIFIER LETTER VOICING -> 'V' */ + { 0xED, 0x3D }, /* MODIFIER LETTER UNASPIRATED -> '=' */ + { 0xEE, 0x22 }, /* MODIFIER LETTER DOUBLE APOSTROPHE -> '"' */ + /* Entries for page 0x03 */ + { 0x63, 0x61 }, /* COMBINING LATIN SMALL LETTER A -> 'a' */ + { 0x64, 0x65 }, /* COMBINING LATIN SMALL LETTER E -> 'e' */ + { 0x65, 0x69 }, /* COMBINING LATIN SMALL LETTER I -> 'i' */ + { 0x66, 0x6F }, /* COMBINING LATIN SMALL LETTER O -> 'o' */ + { 0x67, 0x75 }, /* COMBINING LATIN SMALL LETTER U -> 'u' */ + { 0x68, 0x63 }, /* COMBINING LATIN SMALL LETTER C -> 'c' */ + { 0x69, 0x64 }, /* COMBINING LATIN SMALL LETTER D -> 'd' */ + { 0x6A, 0x68 }, /* COMBINING LATIN SMALL LETTER H -> 'h' */ + { 0x6B, 0x6D }, /* COMBINING LATIN SMALL LETTER M -> 'm' */ + { 0x6C, 0x72 }, /* COMBINING LATIN SMALL LETTER R -> 'r' */ + { 0x6D, 0x74 }, /* COMBINING LATIN SMALL LETTER T -> 't' */ + { 0x6E, 0x76 }, /* COMBINING LATIN SMALL LETTER V -> 'v' */ + { 0x6F, 0x78 }, /* COMBINING LATIN SMALL LETTER X -> 'x' */ + { 0x74, 0x27 }, /* GREEK NUMERAL SIGN -> ''' */ + { 0x75, 0x2C }, /* GREEK LOWER NUMERAL SIGN -> ',' */ + { 0x7E, 0x3F }, /* GREEK QUESTION MARK -> '?' */ + { 0x86, 0x41 }, /* GREEK CAPITAL LETTER ALPHA WITH TONOS -> 'A' */ + { 0x87, 0x3B }, /* GREEK ANO TELEIA -> ';' */ + { 0x88, 0x45 }, /* GREEK CAPITAL LETTER EPSILON WITH TONOS -> 'E' */ + { 0x89, 0x45 }, /* GREEK CAPITAL LETTER ETA WITH TONOS -> 'E' */ + { 0x8A, 0x49 }, /* GREEK CAPITAL LETTER IOTA WITH TONOS -> 'I' */ + { 0x8C, 0x4F }, /* GREEK CAPITAL LETTER OMICRON WITH TONOS -> 'O' */ + { 0x8E, 0x55 }, /* GREEK CAPITAL LETTER UPSILON WITH TONOS -> 'U' */ + { 0x8F, 0x4F }, /* GREEK CAPITAL LETTER OMEGA WITH TONOS -> 'O' */ + { 0x90, 0x49 }, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS -> 'I' */ + { 0x91, 0x41 }, /* GREEK CAPITAL LETTER ALPHA -> 'A' */ + { 0x92, 0x42 }, /* GREEK CAPITAL LETTER BETA -> 'B' */ + { 0x93, 0x47 }, /* GREEK CAPITAL LETTER GAMMA -> 'G' */ + { 0x94, 0x44 }, /* GREEK CAPITAL LETTER DELTA -> 'D' */ + { 0x95, 0x45 }, /* GREEK CAPITAL LETTER EPSILON -> 'E' */ + { 0x96, 0x5A }, /* GREEK CAPITAL LETTER ZETA -> 'Z' */ + { 0x97, 0x45 }, /* GREEK CAPITAL LETTER ETA -> 'E' */ + { 0x99, 0x49 }, /* GREEK CAPITAL LETTER IOTA -> 'I' */ + { 0x9A, 0x4B }, /* GREEK CAPITAL LETTER KAPPA -> 'K' */ + { 0x9B, 0x4C }, /* GREEK CAPITAL LETTER LAMDA -> 'L' */ + { 0x9C, 0x4D }, /* GREEK CAPITAL LETTER MU -> 'M' */ + { 0x9D, 0x4E }, /* GREEK CAPITAL LETTER NU -> 'N' */ + { 0x9F, 0x4F }, /* GREEK CAPITAL LETTER OMICRON -> 'O' */ + { 0xA0, 0x50 }, /* GREEK CAPITAL LETTER PI -> 'P' */ + { 0xA1, 0x52 }, /* GREEK CAPITAL LETTER RHO -> 'R' */ + { 0xA3, 0x53 }, /* GREEK CAPITAL LETTER SIGMA -> 'S' */ + { 0xA4, 0x54 }, /* GREEK CAPITAL LETTER TAU -> 'T' */ + { 0xA5, 0x55 }, /* GREEK CAPITAL LETTER UPSILON -> 'U' */ + { 0xA9, 0x4F }, /* GREEK CAPITAL LETTER OMEGA -> 'O' */ + { 0xAA, 0x49 }, /* GREEK CAPITAL LETTER IOTA WITH DIALYTIKA -> 'I' */ + { 0xAB, 0x55 }, /* GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA -> 'U' */ + { 0xAC, 0x61 }, /* GREEK SMALL LETTER ALPHA WITH TONOS -> 'a' */ + { 0xAD, 0x65 }, /* GREEK SMALL LETTER EPSILON WITH TONOS -> 'e' */ + { 0xAE, 0x65 }, /* GREEK SMALL LETTER ETA WITH TONOS -> 'e' */ + { 0xAF, 0x69 }, /* GREEK SMALL LETTER IOTA WITH TONOS -> 'i' */ + { 0xB0, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS -> 'u' */ + { 0xB1, 0x61 }, /* GREEK SMALL LETTER ALPHA -> 'a' */ + { 0xB2, 0x62 }, /* GREEK SMALL LETTER BETA -> 'b' */ + { 0xB3, 0x67 }, /* GREEK SMALL LETTER GAMMA -> 'g' */ + { 0xB4, 0x64 }, /* GREEK SMALL LETTER DELTA -> 'd' */ + { 0xB5, 0x65 }, /* GREEK SMALL LETTER EPSILON -> 'e' */ + { 0xB6, 0x7A }, /* GREEK SMALL LETTER ZETA -> 'z' */ + { 0xB7, 0x65 }, /* GREEK SMALL LETTER ETA -> 'e' */ + { 0xB9, 0x69 }, /* GREEK SMALL LETTER IOTA -> 'i' */ + { 0xBA, 0x6B }, /* GREEK SMALL LETTER KAPPA -> 'k' */ + { 0xBB, 0x6C }, /* GREEK SMALL LETTER LAMDA -> 'l' */ + { 0xBC, 0x6D }, /* GREEK SMALL LETTER MU -> 'm' */ + { 0xBD, 0x6E }, /* GREEK SMALL LETTER NU -> 'n' */ + { 0xBE, 0x78 }, /* GREEK SMALL LETTER XI -> 'x' */ + { 0xBF, 0x6F }, /* GREEK SMALL LETTER OMICRON -> 'o' */ + { 0xC0, 0x70 }, /* GREEK SMALL LETTER PI -> 'p' */ + { 0xC1, 0x72 }, /* GREEK SMALL LETTER RHO -> 'r' */ + { 0xC2, 0x73 }, /* GREEK SMALL LETTER FINAL SIGMA -> 's' */ + { 0xC3, 0x73 }, /* GREEK SMALL LETTER SIGMA -> 's' */ + { 0xC4, 0x74 }, /* GREEK SMALL LETTER TAU -> 't' */ + { 0xC5, 0x75 }, /* GREEK SMALL LETTER UPSILON -> 'u' */ + { 0xC9, 0x6F }, /* GREEK SMALL LETTER OMEGA -> 'o' */ + { 0xCA, 0x69 }, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA -> 'i' */ + { 0xCB, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA -> 'u' */ + { 0xCC, 0x6F }, /* GREEK SMALL LETTER OMICRON WITH TONOS -> 'o' */ + { 0xCD, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH TONOS -> 'u' */ + { 0xCE, 0x6F }, /* GREEK SMALL LETTER OMEGA WITH TONOS -> 'o' */ + { 0xD0, 0x62 }, /* GREEK BETA SYMBOL -> 'b' */ + { 0xD2, 0x00 }, /* GREEK UPSILON WITH HOOK SYMBOL -> ... */ + { 0xD4, 0x55 }, /* GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL -> 'U' */ + { 0xD6, 0x70 }, /* GREEK PI SYMBOL -> 'p' */ + { 0xD7, 0x26 }, /* GREEK KAI SYMBOL -> '&' */ + { 0xDC, 0x57 }, /* GREEK LETTER DIGAMMA -> 'W' */ + { 0xDD, 0x77 }, /* GREEK SMALL LETTER DIGAMMA -> 'w' */ + { 0xDE, 0x51 }, /* GREEK LETTER KOPPA -> 'Q' */ + { 0xDF, 0x71 }, /* GREEK SMALL LETTER KOPPA -> 'q' */ + { 0xE4, 0x46 }, /* COPTIC CAPITAL LETTER FEI -> 'F' */ + { 0xE5, 0x66 }, /* COPTIC SMALL LETTER FEI -> 'f' */ + { 0xE8, 0x48 }, /* COPTIC CAPITAL LETTER HORI -> 'H' */ + { 0xE9, 0x68 }, /* COPTIC SMALL LETTER HORI -> 'h' */ + { 0xEA, 0x47 }, /* COPTIC CAPITAL LETTER GANGIA -> 'G' */ + { 0xEB, 0x67 }, /* COPTIC SMALL LETTER GANGIA -> 'g' */ + { 0xF0, 0x6B }, /* GREEK KAPPA SYMBOL -> 'k' */ + { 0xF1, 0x72 }, /* GREEK RHO SYMBOL -> 'r' */ + { 0xF2, 0x63 }, /* GREEK LUNATE SIGMA SYMBOL -> 'c' */ + { 0xF3, 0x6A }, /* GREEK LETTER YOT -> 'j' */ + /* Entries for page 0x04 */ + { 0x06, 0x49 }, /* CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I -> 'I' */ + { 0x08, 0x4A }, /* CYRILLIC CAPITAL LETTER JE -> 'J' */ + { 0x0D, 0x49 }, /* CYRILLIC CAPITAL LETTER I WITH GRAVE -> 'I' */ + { 0x0E, 0x55 }, /* CYRILLIC CAPITAL LETTER SHORT U -> 'U' */ + { 0x10, 0x41 }, /* CYRILLIC CAPITAL LETTER A -> 'A' */ + { 0x11, 0x42 }, /* CYRILLIC CAPITAL LETTER BE -> 'B' */ + { 0x12, 0x56 }, /* CYRILLIC CAPITAL LETTER VE -> 'V' */ + { 0x13, 0x47 }, /* CYRILLIC CAPITAL LETTER GHE -> 'G' */ + { 0x14, 0x44 }, /* CYRILLIC CAPITAL LETTER DE -> 'D' */ + { 0x15, 0x45 }, /* CYRILLIC CAPITAL LETTER IE -> 'E' */ + { 0x17, 0x5A }, /* CYRILLIC CAPITAL LETTER ZE -> 'Z' */ + { 0x18, 0x49 }, /* CYRILLIC CAPITAL LETTER I -> 'I' */ + { 0x19, 0x49 }, /* CYRILLIC CAPITAL LETTER SHORT I -> 'I' */ + { 0x1A, 0x4B }, /* CYRILLIC CAPITAL LETTER KA -> 'K' */ + { 0x1B, 0x4C }, /* CYRILLIC CAPITAL LETTER EL -> 'L' */ + { 0x1C, 0x4D }, /* CYRILLIC CAPITAL LETTER EM -> 'M' */ + { 0x1D, 0x4E }, /* CYRILLIC CAPITAL LETTER EN -> 'N' */ + { 0x1E, 0x4F }, /* CYRILLIC CAPITAL LETTER O -> 'O' */ + { 0x1F, 0x50 }, /* CYRILLIC CAPITAL LETTER PE -> 'P' */ + { 0x20, 0x52 }, /* CYRILLIC CAPITAL LETTER ER -> 'R' */ + { 0x21, 0x53 }, /* CYRILLIC CAPITAL LETTER ES -> 'S' */ + { 0x22, 0x54 }, /* CYRILLIC CAPITAL LETTER TE -> 'T' */ + { 0x23, 0x55 }, /* CYRILLIC CAPITAL LETTER U -> 'U' */ + { 0x24, 0x46 }, /* CYRILLIC CAPITAL LETTER EF -> 'F' */ + { 0x2A, 0x27 }, /* CYRILLIC CAPITAL LETTER HARD SIGN -> ''' */ + { 0x2B, 0x59 }, /* CYRILLIC CAPITAL LETTER YERU -> 'Y' */ + { 0x2C, 0x27 }, /* CYRILLIC CAPITAL LETTER SOFT SIGN -> ''' */ + { 0x2D, 0x45 }, /* CYRILLIC CAPITAL LETTER E -> 'E' */ + { 0x30, 0x61 }, /* CYRILLIC SMALL LETTER A -> 'a' */ + { 0x31, 0x62 }, /* CYRILLIC SMALL LETTER BE -> 'b' */ + { 0x32, 0x76 }, /* CYRILLIC SMALL LETTER VE -> 'v' */ + { 0x33, 0x67 }, /* CYRILLIC SMALL LETTER GHE -> 'g' */ + { 0x34, 0x64 }, /* CYRILLIC SMALL LETTER DE -> 'd' */ + { 0x35, 0x65 }, /* CYRILLIC SMALL LETTER IE -> 'e' */ + { 0x37, 0x7A }, /* CYRILLIC SMALL LETTER ZE -> 'z' */ + { 0x38, 0x69 }, /* CYRILLIC SMALL LETTER I -> 'i' */ + { 0x39, 0x69 }, /* CYRILLIC SMALL LETTER SHORT I -> 'i' */ + { 0x3A, 0x6B }, /* CYRILLIC SMALL LETTER KA -> 'k' */ + { 0x3B, 0x6C }, /* CYRILLIC SMALL LETTER EL -> 'l' */ + { 0x3C, 0x6D }, /* CYRILLIC SMALL LETTER EM -> 'm' */ + { 0x3D, 0x6E }, /* CYRILLIC SMALL LETTER EN -> 'n' */ + { 0x3E, 0x6F }, /* CYRILLIC SMALL LETTER O -> 'o' */ + { 0x3F, 0x70 }, /* CYRILLIC SMALL LETTER PE -> 'p' */ + { 0x40, 0x72 }, /* CYRILLIC SMALL LETTER ER -> 'r' */ + { 0x41, 0x73 }, /* CYRILLIC SMALL LETTER ES -> 's' */ + { 0x42, 0x74 }, /* CYRILLIC SMALL LETTER TE -> 't' */ + { 0x43, 0x75 }, /* CYRILLIC SMALL LETTER U -> 'u' */ + { 0x44, 0x66 }, /* CYRILLIC SMALL LETTER EF -> 'f' */ + { 0x4A, 0x27 }, /* CYRILLIC SMALL LETTER HARD SIGN -> ''' */ + { 0x4B, 0x79 }, /* CYRILLIC SMALL LETTER YERU -> 'y' */ + { 0x4C, 0x27 }, /* CYRILLIC SMALL LETTER SOFT SIGN -> ''' */ + { 0x4D, 0x65 }, /* CYRILLIC SMALL LETTER E -> 'e' */ + { 0x56, 0x69 }, /* CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -> 'i' */ + { 0x58, 0x6A }, /* CYRILLIC SMALL LETTER JE -> 'j' */ + { 0x5D, 0x69 }, /* CYRILLIC SMALL LETTER I WITH GRAVE -> 'i' */ + { 0x5E, 0x75 }, /* CYRILLIC SMALL LETTER SHORT U -> 'u' */ + { 0x60, 0x4F }, /* CYRILLIC CAPITAL LETTER OMEGA -> 'O' */ + { 0x61, 0x6F }, /* CYRILLIC SMALL LETTER OMEGA -> 'o' */ + { 0x62, 0x45 }, /* CYRILLIC CAPITAL LETTER YAT -> 'E' */ + { 0x63, 0x65 }, /* CYRILLIC SMALL LETTER YAT -> 'e' */ + { 0x66, 0x45 }, /* CYRILLIC CAPITAL LETTER LITTLE YUS -> 'E' */ + { 0x67, 0x65 }, /* CYRILLIC SMALL LETTER LITTLE YUS -> 'e' */ + { 0x6A, 0x4F }, /* CYRILLIC CAPITAL LETTER BIG YUS -> 'O' */ + { 0x6B, 0x6F }, /* CYRILLIC SMALL LETTER BIG YUS -> 'o' */ + { 0x72, 0x46 }, /* CYRILLIC CAPITAL LETTER FITA -> 'F' */ + { 0x73, 0x66 }, /* CYRILLIC SMALL LETTER FITA -> 'f' */ + { 0x74, 0x59 }, /* CYRILLIC CAPITAL LETTER IZHITSA -> 'Y' */ + { 0x75, 0x79 }, /* CYRILLIC SMALL LETTER IZHITSA -> 'y' */ + { 0x76, 0x59 }, /* CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT -> 'Y' */ + { 0x77, 0x79 }, /* CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT -> 'y' */ + { 0x78, 0x75 }, /* CYRILLIC CAPITAL LETTER UK -> 'u' */ + { 0x79, 0x75 }, /* CYRILLIC SMALL LETTER UK -> 'u' */ + { 0x7A, 0x4F }, /* CYRILLIC CAPITAL LETTER ROUND OMEGA -> 'O' */ + { 0x7B, 0x6F }, /* CYRILLIC SMALL LETTER ROUND OMEGA -> 'o' */ + { 0x7C, 0x4F }, /* CYRILLIC CAPITAL LETTER OMEGA WITH TITLO -> 'O' */ + { 0x7D, 0x6F }, /* CYRILLIC SMALL LETTER OMEGA WITH TITLO -> 'o' */ + { 0x80, 0x51 }, /* CYRILLIC CAPITAL LETTER KOPPA -> 'Q' */ + { 0x81, 0x71 }, /* CYRILLIC SMALL LETTER KOPPA -> 'q' */ + { 0x8C, 0x22 }, /* CYRILLIC CAPITAL LETTER SEMISOFT SIGN -> '"' */ + { 0x8D, 0x22 }, /* CYRILLIC SMALL LETTER SEMISOFT SIGN -> '"' */ + { 0xAE, 0x55 }, /* CYRILLIC CAPITAL LETTER STRAIGHT U -> 'U' */ + { 0xAF, 0x75 }, /* CYRILLIC SMALL LETTER STRAIGHT U -> 'u' */ + { 0xBA, 0x48 }, /* CYRILLIC CAPITAL LETTER SHHA -> 'H' */ + { 0xBB, 0x68 }, /* CYRILLIC SMALL LETTER SHHA -> 'h' */ + { 0xC0, 0x60 }, /* CYRILLIC LETTER PALOCHKA -> '`' */ + { 0xD0, 0x61 }, /* CYRILLIC CAPITAL LETTER A WITH BREVE -> 'a' */ + { 0xD1, 0x61 }, /* CYRILLIC SMALL LETTER A WITH BREVE -> 'a' */ + { 0xD2, 0x41 }, /* CYRILLIC CAPITAL LETTER A WITH DIAERESIS -> 'A' */ + { 0xD3, 0x61 }, /* CYRILLIC SMALL LETTER A WITH DIAERESIS -> 'a' */ + { 0xD8, 0x00 }, /* CYRILLIC CAPITAL LETTER SCHWA -> ... */ + { 0xDB, 0x40 }, /* CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS -> '@' */ + { 0xDE, 0x5A }, /* CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS -> 'Z' */ + { 0xDF, 0x7A }, /* CYRILLIC SMALL LETTER ZE WITH DIAERESIS -> 'z' */ + { 0xE2, 0x49 }, /* CYRILLIC CAPITAL LETTER I WITH MACRON -> 'I' */ + { 0xE3, 0x69 }, /* CYRILLIC SMALL LETTER I WITH MACRON -> 'i' */ + { 0xE4, 0x49 }, /* CYRILLIC CAPITAL LETTER I WITH DIAERESIS -> 'I' */ + { 0xE5, 0x69 }, /* CYRILLIC SMALL LETTER I WITH DIAERESIS -> 'i' */ + { 0xE6, 0x4F }, /* CYRILLIC CAPITAL LETTER O WITH DIAERESIS -> 'O' */ + { 0xE7, 0x6F }, /* CYRILLIC SMALL LETTER O WITH DIAERESIS -> 'o' */ + { 0xE8, 0x4F }, /* CYRILLIC CAPITAL LETTER BARRED O -> 'O' */ + { 0xE9, 0x6F }, /* CYRILLIC SMALL LETTER BARRED O -> 'o' */ + { 0xEA, 0x4F }, /* CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS -> 'O' */ + { 0xEB, 0x6F }, /* CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS -> 'o' */ + { 0xEC, 0x45 }, /* CYRILLIC CAPITAL LETTER E WITH DIAERESIS -> 'E' */ + { 0xED, 0x65 }, /* CYRILLIC SMALL LETTER E WITH DIAERESIS -> 'e' */ + { 0xEE, 0x55 }, /* CYRILLIC CAPITAL LETTER U WITH MACRON -> 'U' */ + { 0xEF, 0x75 }, /* CYRILLIC SMALL LETTER U WITH MACRON -> 'u' */ + { 0xF0, 0x55 }, /* CYRILLIC CAPITAL LETTER U WITH DIAERESIS -> 'U' */ + { 0xF1, 0x75 }, /* CYRILLIC SMALL LETTER U WITH DIAERESIS -> 'u' */ + { 0xF2, 0x55 }, /* CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE -> 'U' */ + { 0xF3, 0x75 }, /* CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE -> 'u' */ + { 0xF8, 0x59 }, /* CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS -> 'Y' */ + { 0xF9, 0x79 }, /* CYRILLIC SMALL LETTER YERU WITH DIAERESIS -> 'y' */ + /* Entries for page 0x05 */ + { 0x31, 0x41 }, /* ARMENIAN CAPITAL LETTER AYB -> 'A' */ + { 0x32, 0x42 }, /* ARMENIAN CAPITAL LETTER BEN -> 'B' */ + { 0x33, 0x47 }, /* ARMENIAN CAPITAL LETTER GIM -> 'G' */ + { 0x34, 0x44 }, /* ARMENIAN CAPITAL LETTER DA -> 'D' */ + { 0x35, 0x45 }, /* ARMENIAN CAPITAL LETTER ECH -> 'E' */ + { 0x36, 0x5A }, /* ARMENIAN CAPITAL LETTER ZA -> 'Z' */ + { 0x37, 0x45 }, /* ARMENIAN CAPITAL LETTER EH -> 'E' */ + { 0x38, 0x45 }, /* ARMENIAN CAPITAL LETTER ET -> 'E' */ + { 0x3B, 0x49 }, /* ARMENIAN CAPITAL LETTER INI -> 'I' */ + { 0x3C, 0x4C }, /* ARMENIAN CAPITAL LETTER LIWN -> 'L' */ + { 0x3F, 0x4B }, /* ARMENIAN CAPITAL LETTER KEN -> 'K' */ + { 0x40, 0x48 }, /* ARMENIAN CAPITAL LETTER HO -> 'H' */ + { 0x44, 0x4D }, /* ARMENIAN CAPITAL LETTER MEN -> 'M' */ + { 0x45, 0x59 }, /* ARMENIAN CAPITAL LETTER YI -> 'Y' */ + { 0x46, 0x4E }, /* ARMENIAN CAPITAL LETTER NOW -> 'N' */ + { 0x48, 0x4F }, /* ARMENIAN CAPITAL LETTER VO -> 'O' */ + { 0x4A, 0x50 }, /* ARMENIAN CAPITAL LETTER PEH -> 'P' */ + { 0x4B, 0x4A }, /* ARMENIAN CAPITAL LETTER JHEH -> 'J' */ + { 0x4D, 0x53 }, /* ARMENIAN CAPITAL LETTER SEH -> 'S' */ + { 0x4E, 0x56 }, /* ARMENIAN CAPITAL LETTER VEW -> 'V' */ + { 0x4F, 0x54 }, /* ARMENIAN CAPITAL LETTER TIWN -> 'T' */ + { 0x50, 0x52 }, /* ARMENIAN CAPITAL LETTER REH -> 'R' */ + { 0x52, 0x57 }, /* ARMENIAN CAPITAL LETTER YIWN -> 'W' */ + { 0x55, 0x4F }, /* ARMENIAN CAPITAL LETTER OH -> 'O' */ + { 0x56, 0x46 }, /* ARMENIAN CAPITAL LETTER FEH -> 'F' */ + { 0x59, 0x3C }, /* ARMENIAN MODIFIER LETTER LEFT HALF RING -> '<' */ + { 0x5A, 0x27 }, /* ARMENIAN APOSTROPHE -> ''' */ + { 0x5B, 0x2F }, /* ARMENIAN EMPHASIS MARK -> '/' */ + { 0x5C, 0x21 }, /* ARMENIAN EXCLAMATION MARK -> '!' */ + { 0x5D, 0x2C }, /* ARMENIAN COMMA -> ',' */ + { 0x5E, 0x3F }, /* ARMENIAN QUESTION MARK -> '?' */ + { 0x5F, 0x2E }, /* ARMENIAN ABBREVIATION MARK -> '.' */ + { 0x61, 0x61 }, /* ARMENIAN SMALL LETTER AYB -> 'a' */ + { 0x62, 0x62 }, /* ARMENIAN SMALL LETTER BEN -> 'b' */ + { 0x63, 0x67 }, /* ARMENIAN SMALL LETTER GIM -> 'g' */ + { 0x64, 0x64 }, /* ARMENIAN SMALL LETTER DA -> 'd' */ + { 0x65, 0x65 }, /* ARMENIAN SMALL LETTER ECH -> 'e' */ + { 0x66, 0x7A }, /* ARMENIAN SMALL LETTER ZA -> 'z' */ + { 0x67, 0x65 }, /* ARMENIAN SMALL LETTER EH -> 'e' */ + { 0x68, 0x65 }, /* ARMENIAN SMALL LETTER ET -> 'e' */ + { 0x6B, 0x69 }, /* ARMENIAN SMALL LETTER INI -> 'i' */ + { 0x6C, 0x6C }, /* ARMENIAN SMALL LETTER LIWN -> 'l' */ + { 0x6F, 0x6B }, /* ARMENIAN SMALL LETTER KEN -> 'k' */ + { 0x70, 0x68 }, /* ARMENIAN SMALL LETTER HO -> 'h' */ + { 0x74, 0x6D }, /* ARMENIAN SMALL LETTER MEN -> 'm' */ + { 0x75, 0x79 }, /* ARMENIAN SMALL LETTER YI -> 'y' */ + { 0x76, 0x6E }, /* ARMENIAN SMALL LETTER NOW -> 'n' */ + { 0x78, 0x6F }, /* ARMENIAN SMALL LETTER VO -> 'o' */ + { 0x7A, 0x70 }, /* ARMENIAN SMALL LETTER PEH -> 'p' */ + { 0x7B, 0x6A }, /* ARMENIAN SMALL LETTER JHEH -> 'j' */ + { 0x7D, 0x73 }, /* ARMENIAN SMALL LETTER SEH -> 's' */ + { 0x7E, 0x76 }, /* ARMENIAN SMALL LETTER VEW -> 'v' */ + { 0x7F, 0x74 }, /* ARMENIAN SMALL LETTER TIWN -> 't' */ + { 0x80, 0x72 }, /* ARMENIAN SMALL LETTER REH -> 'r' */ + { 0x82, 0x77 }, /* ARMENIAN SMALL LETTER YIWN -> 'w' */ + { 0x85, 0x6F }, /* ARMENIAN SMALL LETTER OH -> 'o' */ + { 0x86, 0x66 }, /* ARMENIAN SMALL LETTER FEH -> 'f' */ + { 0x89, 0x3A }, /* ARMENIAN FULL STOP -> ':' */ + { 0x8A, 0x2D }, /* ARMENIAN HYPHEN -> '-' */ + { 0xB1, 0x65 }, /* HEBREW POINT HATAF SEGOL -> 'e' */ + { 0xB2, 0x61 }, /* HEBREW POINT HATAF PATAH -> 'a' */ + { 0xB3, 0x6F }, /* HEBREW POINT HATAF QAMATS -> 'o' */ + { 0xB4, 0x69 }, /* HEBREW POINT HIRIQ -> 'i' */ + { 0xB5, 0x65 }, /* HEBREW POINT TSERE -> 'e' */ + { 0xB6, 0x65 }, /* HEBREW POINT SEGOL -> 'e' */ + { 0xB7, 0x61 }, /* HEBREW POINT PATAH -> 'a' */ + { 0xB8, 0x61 }, /* HEBREW POINT QAMATS -> 'a' */ + { 0xB9, 0x6F }, /* HEBREW POINT HOLAM -> 'o' */ + { 0xBA, 0x6F }, /* HEBREW POINT HOLAM HASER FOR VAV -> 'o' */ + { 0xBB, 0x75 }, /* HEBREW POINT QUBUTS -> 'u' */ + { 0xBE, 0x2D }, /* HEBREW PUNCTUATION MAQAF -> '-' */ + { 0xC0, 0x7C }, /* HEBREW PUNCTUATION PASEQ -> '|' */ + { 0xC3, 0x2E }, /* HEBREW PUNCTUATION SOF PASUQ -> '.' */ + { 0xC6, 0x6E }, /* HEBREW PUNCTUATION NUN HAFUKHA -> 'n' */ + { 0xC7, 0x6F }, /* HEBREW POINT QAMATS QATAN -> 'o' */ + { 0xD0, 0x41 }, /* HEBREW LETTER ALEF -> 'A' */ + { 0xD1, 0x62 }, /* HEBREW LETTER BET -> 'b' */ + { 0xD2, 0x67 }, /* HEBREW LETTER GIMEL -> 'g' */ + { 0xD3, 0x64 }, /* HEBREW LETTER DALET -> 'd' */ + { 0xD4, 0x68 }, /* HEBREW LETTER HE -> 'h' */ + { 0xD5, 0x76 }, /* HEBREW LETTER VAV -> 'v' */ + { 0xD6, 0x7A }, /* HEBREW LETTER ZAYIN -> 'z' */ + { 0xD7, 0x48 }, /* HEBREW LETTER HET -> 'H' */ + { 0xD8, 0x54 }, /* HEBREW LETTER TET -> 'T' */ + { 0xD9, 0x79 }, /* HEBREW LETTER YOD -> 'y' */ + { 0xDC, 0x6C }, /* HEBREW LETTER LAMED -> 'l' */ + { 0xDD, 0x6D }, /* HEBREW LETTER FINAL MEM -> 'm' */ + { 0xDE, 0x6D }, /* HEBREW LETTER MEM -> 'm' */ + { 0xDF, 0x6E }, /* HEBREW LETTER FINAL NUN -> 'n' */ + { 0xE0, 0x6E }, /* HEBREW LETTER NUN -> 'n' */ + { 0xE1, 0x73 }, /* HEBREW LETTER SAMEKH -> 's' */ + { 0xE2, 0x60 }, /* HEBREW LETTER AYIN -> '`' */ + { 0xE3, 0x70 }, /* HEBREW LETTER FINAL PE -> 'p' */ + { 0xE4, 0x70 }, /* HEBREW LETTER PE -> 'p' */ + { 0xE7, 0x6B }, /* HEBREW LETTER QOF -> 'k' */ + { 0xE8, 0x72 }, /* HEBREW LETTER RESH -> 'r' */ + { 0xEA, 0x74 }, /* HEBREW LETTER TAV -> 't' */ + { 0xF0, 0x56 }, /* HEBREW LIGATURE YIDDISH DOUBLE VAV -> 'V' */ + { 0xF3, 0x27 }, /* HEBREW PUNCTUATION GERESH -> ''' */ + { 0xF4, 0x22 }, /* HEBREW PUNCTUATION GERSHAYIM -> '"' */ + /* Entries for page 0x06 */ + { 0x0C, 0x2C }, /* ARABIC COMMA -> ',' */ + { 0x1B, 0x3B }, /* ARABIC SEMICOLON -> ';' */ + { 0x1F, 0x3F }, /* ARABIC QUESTION MARK -> '?' */ + { 0x22, 0x61 }, /* ARABIC LETTER ALEF WITH MADDA ABOVE -> 'a' */ + { 0x23, 0x27 }, /* ARABIC LETTER ALEF WITH HAMZA ABOVE -> ''' */ + { 0x28, 0x62 }, /* ARABIC LETTER BEH -> 'b' */ + { 0x29, 0x40 }, /* ARABIC LETTER TEH MARBUTA -> '@' */ + { 0x2A, 0x74 }, /* ARABIC LETTER TEH -> 't' */ + { 0x2C, 0x6A }, /* ARABIC LETTER JEEM -> 'j' */ + { 0x2D, 0x48 }, /* ARABIC LETTER HAH -> 'H' */ + { 0x2F, 0x64 }, /* ARABIC LETTER DAL -> 'd' */ + { 0x31, 0x72 }, /* ARABIC LETTER REH -> 'r' */ + { 0x32, 0x7A }, /* ARABIC LETTER ZAIN -> 'z' */ + { 0x33, 0x73 }, /* ARABIC LETTER SEEN -> 's' */ + { 0x35, 0x53 }, /* ARABIC LETTER SAD -> 'S' */ + { 0x36, 0x44 }, /* ARABIC LETTER DAD -> 'D' */ + { 0x37, 0x54 }, /* ARABIC LETTER TAH -> 'T' */ + { 0x38, 0x5A }, /* ARABIC LETTER ZAH -> 'Z' */ + { 0x39, 0x60 }, /* ARABIC LETTER AIN -> '`' */ + { 0x3A, 0x47 }, /* ARABIC LETTER GHAIN -> 'G' */ + { 0x41, 0x66 }, /* ARABIC LETTER FEH -> 'f' */ + { 0x42, 0x71 }, /* ARABIC LETTER QAF -> 'q' */ + { 0x43, 0x6B }, /* ARABIC LETTER KAF -> 'k' */ + { 0x44, 0x6C }, /* ARABIC LETTER LAM -> 'l' */ + { 0x45, 0x6D }, /* ARABIC LETTER MEEM -> 'm' */ + { 0x46, 0x6E }, /* ARABIC LETTER NOON -> 'n' */ + { 0x47, 0x68 }, /* ARABIC LETTER HEH -> 'h' */ + { 0x48, 0x77 }, /* ARABIC LETTER WAW -> 'w' */ + { 0x49, 0x7E }, /* ARABIC LETTER ALEF MAKSURA -> '~' */ + { 0x4A, 0x79 }, /* ARABIC LETTER YEH -> 'y' */ + { 0x4E, 0x61 }, /* ARABIC FATHA -> 'a' */ + { 0x4F, 0x75 }, /* ARABIC DAMMA -> 'u' */ + { 0x50, 0x69 }, /* ARABIC KASRA -> 'i' */ + { 0x51, 0x57 }, /* ARABIC SHADDA -> 'W' */ + { 0x54, 0x27 }, /* ARABIC HAMZA ABOVE -> ''' */ + { 0x55, 0x27 }, /* ARABIC HAMZA BELOW -> ''' */ + { 0x60, 0x30 }, /* ARABIC-INDIC DIGIT ZERO -> '0' */ + { 0x61, 0x31 }, /* ARABIC-INDIC DIGIT ONE -> '1' */ + { 0x62, 0x32 }, /* ARABIC-INDIC DIGIT TWO -> '2' */ + { 0x63, 0x33 }, /* ARABIC-INDIC DIGIT THREE -> '3' */ + { 0x64, 0x34 }, /* ARABIC-INDIC DIGIT FOUR -> '4' */ + { 0x65, 0x35 }, /* ARABIC-INDIC DIGIT FIVE -> '5' */ + { 0x66, 0x36 }, /* ARABIC-INDIC DIGIT SIX -> '6' */ + { 0x67, 0x37 }, /* ARABIC-INDIC DIGIT SEVEN -> '7' */ + { 0x68, 0x38 }, /* ARABIC-INDIC DIGIT EIGHT -> '8' */ + { 0x69, 0x39 }, /* ARABIC-INDIC DIGIT NINE -> '9' */ + { 0x6A, 0x25 }, /* ARABIC PERCENT SIGN -> '%' */ + { 0x6B, 0x2E }, /* ARABIC DECIMAL SEPARATOR -> '.' */ + { 0x6C, 0x2C }, /* ARABIC THOUSANDS SEPARATOR -> ',' */ + { 0x6D, 0x2A }, /* ARABIC FIVE POINTED STAR -> '*' */ + { 0x71, 0x00 }, /* ARABIC LETTER ALEF WASLA -> ... */ + { 0x73, 0x27 }, /* ARABIC LETTER ALEF WITH WAVY HAMZA BELOW -> ''' */ + { 0x75, 0x27 }, /* ARABIC LETTER HIGH HAMZA ALEF -> ''' */ + { 0x7B, 0x62 }, /* ARABIC LETTER BEEH -> 'b' */ + { 0x7C, 0x74 }, /* ARABIC LETTER TEH WITH RING -> 't' */ + { 0x7D, 0x54 }, /* ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS -> 'T' */ + { 0x7E, 0x70 }, /* ARABIC LETTER PEH -> 'p' */ + { 0x82, 0x48 }, /* ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE -> 'H' */ + { 0x85, 0x48 }, /* ARABIC LETTER HAH WITH THREE DOTS ABOVE -> 'H' */ + { 0x89, 0x44 }, /* ARABIC LETTER DAL WITH RING -> 'D' */ + { 0x8A, 0x44 }, /* ARABIC LETTER DAL WITH DOT BELOW -> 'D' */ + { 0x8E, 0x64 }, /* ARABIC LETTER DUL -> 'd' */ + { 0x8F, 0x44 }, /* ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS -> 'D' */ + { 0x90, 0x44 }, /* ARABIC LETTER DAL WITH FOUR DOTS ABOVE -> 'D' */ + { 0x92, 0x00 }, /* ARABIC LETTER REH WITH SMALL V -> ... */ + { 0x97, 0x52 }, /* ARABIC LETTER REH WITH TWO DOTS ABOVE -> 'R' */ + { 0x98, 0x6A }, /* ARABIC LETTER JEH -> 'j' */ + { 0x99, 0x52 }, /* ARABIC LETTER REH WITH FOUR DOTS ABOVE -> 'R' */ + { 0x9A, 0x00 }, /* ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE -> ... */ + { 0x9E, 0x53 }, /* ARABIC LETTER SAD WITH THREE DOTS ABOVE -> 'S' */ + { 0x9F, 0x54 }, /* ARABIC LETTER TAH WITH THREE DOTS ABOVE -> 'T' */ + { 0xA1, 0x00 }, /* ARABIC LETTER DOTLESS FEH -> ... */ + { 0xA3, 0x46 }, /* ARABIC LETTER FEH WITH DOT BELOW -> 'F' */ + { 0xA4, 0x76 }, /* ARABIC LETTER VEH -> 'v' */ + { 0xA5, 0x66 }, /* ARABIC LETTER FEH WITH THREE DOTS BELOW -> 'f' */ + { 0xA7, 0x51 }, /* ARABIC LETTER QAF WITH DOT ABOVE -> 'Q' */ + { 0xA8, 0x51 }, /* ARABIC LETTER QAF WITH THREE DOTS ABOVE -> 'Q' */ + { 0xAA, 0x6B }, /* ARABIC LETTER SWASH KAF -> 'k' */ + { 0xAB, 0x4B }, /* ARABIC LETTER KAF WITH RING -> 'K' */ + { 0xAC, 0x4B }, /* ARABIC LETTER KAF WITH DOT ABOVE -> 'K' */ + { 0xAE, 0x4B }, /* ARABIC LETTER KAF WITH THREE DOTS BELOW -> 'K' */ + { 0xAF, 0x67 }, /* ARABIC LETTER GAF -> 'g' */ + { 0xB0, 0x47 }, /* ARABIC LETTER GAF WITH RING -> 'G' */ + { 0xB1, 0x4E }, /* ARABIC LETTER NGOEH -> 'N' */ + { 0xB2, 0x00 }, /* ARABIC LETTER GAF WITH TWO DOTS BELOW -> ... */ + { 0xB4, 0x47 }, /* ARABIC LETTER GAF WITH THREE DOTS ABOVE -> 'G' */ + { 0xB5, 0x00 }, /* ARABIC LETTER LAM WITH SMALL V -> ... */ + { 0xB8, 0x4C }, /* ARABIC LETTER LAM WITH THREE DOTS BELOW -> 'L' */ + { 0xB9, 0x00 }, /* ARABIC LETTER NOON WITH DOT BELOW -> ... */ + { 0xBD, 0x4E }, /* ARABIC LETTER NOON WITH THREE DOTS ABOVE -> 'N' */ + { 0xBE, 0x68 }, /* ARABIC LETTER HEH DOACHASHMEE -> 'h' */ + { 0xC1, 0x68 }, /* ARABIC LETTER HEH GOAL -> 'h' */ + { 0xC2, 0x48 }, /* ARABIC LETTER HEH GOAL WITH HAMZA ABOVE -> 'H' */ + { 0xC3, 0x40 }, /* ARABIC LETTER TEH MARBUTA GOAL -> '@' */ + { 0xC4, 0x57 }, /* ARABIC LETTER WAW WITH RING -> 'W' */ + { 0xC7, 0x75 }, /* ARABIC LETTER U -> 'u' */ + { 0xCA, 0x57 }, /* ARABIC LETTER WAW WITH TWO DOTS ABOVE -> 'W' */ + { 0xCB, 0x76 }, /* ARABIC LETTER VE -> 'v' */ + { 0xCC, 0x79 }, /* ARABIC LETTER FARSI YEH -> 'y' */ + { 0xCD, 0x59 }, /* ARABIC LETTER YEH WITH TAIL -> 'Y' */ + { 0xCE, 0x59 }, /* ARABIC LETTER YEH WITH SMALL V -> 'Y' */ + { 0xCF, 0x57 }, /* ARABIC LETTER WAW WITH DOT ABOVE -> 'W' */ + { 0xD2, 0x79 }, /* ARABIC LETTER YEH BARREE -> 'y' */ + { 0xD4, 0x2E }, /* ARABIC FULL STOP -> '.' */ + { 0xDD, 0x40 }, /* ARABIC END OF AYAH -> '@' */ + { 0xDE, 0x23 }, /* ARABIC START OF RUB EL HIZB -> '#' */ + { 0xE9, 0x5E }, /* ARABIC PLACE OF SAJDAH -> '^' */ + { 0xF0, 0x30 }, /* EXTENDED ARABIC-INDIC DIGIT ZERO -> '0' */ + { 0xF1, 0x31 }, /* EXTENDED ARABIC-INDIC DIGIT ONE -> '1' */ + { 0xF2, 0x32 }, /* EXTENDED ARABIC-INDIC DIGIT TWO -> '2' */ + { 0xF3, 0x33 }, /* EXTENDED ARABIC-INDIC DIGIT THREE -> '3' */ + { 0xF4, 0x34 }, /* EXTENDED ARABIC-INDIC DIGIT FOUR -> '4' */ + { 0xF5, 0x35 }, /* EXTENDED ARABIC-INDIC DIGIT FIVE -> '5' */ + { 0xF6, 0x36 }, /* EXTENDED ARABIC-INDIC DIGIT SIX -> '6' */ + { 0xF7, 0x37 }, /* EXTENDED ARABIC-INDIC DIGIT SEVEN -> '7' */ + { 0xF8, 0x38 }, /* EXTENDED ARABIC-INDIC DIGIT EIGHT -> '8' */ + { 0xF9, 0x39 }, /* EXTENDED ARABIC-INDIC DIGIT NINE -> '9' */ + { 0xFB, 0x44 }, /* ARABIC LETTER DAD WITH DOT BELOW -> 'D' */ + { 0xFD, 0x26 }, /* ARABIC SIGN SINDHI AMPERSAND -> '&' */ + /* Entries for page 0x07 */ + { 0x01, 0x2F }, /* SYRIAC SUPRALINEAR FULL STOP -> '/' */ + { 0x02, 0x2C }, /* SYRIAC SUBLINEAR FULL STOP -> ',' */ + { 0x03, 0x21 }, /* SYRIAC SUPRALINEAR COLON -> '!' */ + { 0x04, 0x21 }, /* SYRIAC SUBLINEAR COLON -> '!' */ + { 0x05, 0x2D }, /* SYRIAC HORIZONTAL COLON -> '-' */ + { 0x06, 0x2C }, /* SYRIAC COLON SKEWED LEFT -> ',' */ + { 0x07, 0x2C }, /* SYRIAC COLON SKEWED RIGHT -> ',' */ + { 0x08, 0x3B }, /* SYRIAC SUPRALINEAR COLON SKEWED LEFT -> ';' */ + { 0x09, 0x3F }, /* SYRIAC SUBLINEAR COLON SKEWED RIGHT -> '?' */ + { 0x0A, 0x7E }, /* SYRIAC CONTRACTION -> '~' */ + { 0x0B, 0x7B }, /* SYRIAC HARKLEAN OBELUS -> '{' */ + { 0x0C, 0x7D }, /* SYRIAC HARKLEAN METOBELUS -> '}' */ + { 0x0D, 0x2A }, /* SYRIAC HARKLEAN ASTERISCUS -> '*' */ + { 0x10, 0x27 }, /* SYRIAC LETTER ALAPH -> ''' */ + { 0x12, 0x62 }, /* SYRIAC LETTER BETH -> 'b' */ + { 0x13, 0x67 }, /* SYRIAC LETTER GAMAL -> 'g' */ + { 0x14, 0x67 }, /* SYRIAC LETTER GAMAL GARSHUNI -> 'g' */ + { 0x15, 0x64 }, /* SYRIAC LETTER DALATH -> 'd' */ + { 0x16, 0x64 }, /* SYRIAC LETTER DOTLESS DALATH RISH -> 'd' */ + { 0x17, 0x68 }, /* SYRIAC LETTER HE -> 'h' */ + { 0x18, 0x77 }, /* SYRIAC LETTER WAW -> 'w' */ + { 0x19, 0x7A }, /* SYRIAC LETTER ZAIN -> 'z' */ + { 0x1A, 0x48 }, /* SYRIAC LETTER HETH -> 'H' */ + { 0x1B, 0x74 }, /* SYRIAC LETTER TETH -> 't' */ + { 0x1C, 0x74 }, /* SYRIAC LETTER TETH GARSHUNI -> 't' */ + { 0x1D, 0x79 }, /* SYRIAC LETTER YUDH -> 'y' */ + { 0x1F, 0x6B }, /* SYRIAC LETTER KAPH -> 'k' */ + { 0x20, 0x6C }, /* SYRIAC LETTER LAMADH -> 'l' */ + { 0x21, 0x6D }, /* SYRIAC LETTER MIM -> 'm' */ + { 0x22, 0x6E }, /* SYRIAC LETTER NUN -> 'n' */ + { 0x23, 0x73 }, /* SYRIAC LETTER SEMKATH -> 's' */ + { 0x24, 0x73 }, /* SYRIAC LETTER FINAL SEMKATH -> 's' */ + { 0x25, 0x60 }, /* SYRIAC LETTER E -> '`' */ + { 0x26, 0x70 }, /* SYRIAC LETTER PE -> 'p' */ + { 0x27, 0x70 }, /* SYRIAC LETTER REVERSED PE -> 'p' */ + { 0x28, 0x53 }, /* SYRIAC LETTER SADHE -> 'S' */ + { 0x29, 0x71 }, /* SYRIAC LETTER QAPH -> 'q' */ + { 0x2A, 0x72 }, /* SYRIAC LETTER RISH -> 'r' */ + { 0x2C, 0x74 }, /* SYRIAC LETTER TAW -> 't' */ + { 0x30, 0x00 }, /* SYRIAC PTHAHA ABOVE -> ... */ + { 0x32, 0x61 }, /* SYRIAC PTHAHA DOTTED -> 'a' */ + { 0x33, 0x00 }, /* SYRIAC ZQAPHA ABOVE -> ... */ + { 0x35, 0x41 }, /* SYRIAC ZQAPHA DOTTED -> 'A' */ + { 0x36, 0x00 }, /* SYRIAC RBASA ABOVE -> ... */ + { 0x38, 0x65 }, /* SYRIAC DOTTED ZLAMA HORIZONTAL -> 'e' */ + { 0x39, 0x45 }, /* SYRIAC DOTTED ZLAMA ANGULAR -> 'E' */ + { 0x3A, 0x69 }, /* SYRIAC HBASA ABOVE -> 'i' */ + { 0x3B, 0x69 }, /* SYRIAC HBASA BELOW -> 'i' */ + { 0x3C, 0x00 }, /* SYRIAC HBASA-ESASA DOTTED -> ... */ + { 0x3E, 0x75 }, /* SYRIAC ESASA BELOW -> 'u' */ + { 0x3F, 0x6F }, /* SYRIAC RWAHA -> 'o' */ + { 0x41, 0x60 }, /* SYRIAC QUSHSHAYA -> '`' */ + { 0x42, 0x27 }, /* SYRIAC RUKKAKHA -> ''' */ + { 0x45, 0x58 }, /* SYRIAC THREE DOTS ABOVE -> 'X' */ + { 0x46, 0x51 }, /* SYRIAC THREE DOTS BELOW -> 'Q' */ + { 0x47, 0x40 }, /* SYRIAC OBLIQUE LINE ABOVE -> '@' */ + { 0x48, 0x40 }, /* SYRIAC OBLIQUE LINE BELOW -> '@' */ + { 0x49, 0x7C }, /* SYRIAC MUSIC -> '|' */ + { 0x4A, 0x2B }, /* SYRIAC BARREKH -> '+' */ + { 0x80, 0x68 }, /* THAANA LETTER HAA -> 'h' */ + { 0x82, 0x6E }, /* THAANA LETTER NOONU -> 'n' */ + { 0x83, 0x72 }, /* THAANA LETTER RAA -> 'r' */ + { 0x84, 0x62 }, /* THAANA LETTER BAA -> 'b' */ + { 0x85, 0x4C }, /* THAANA LETTER LHAVIYANI -> 'L' */ + { 0x86, 0x6B }, /* THAANA LETTER KAAFU -> 'k' */ + { 0x87, 0x27 }, /* THAANA LETTER ALIFU -> ''' */ + { 0x88, 0x76 }, /* THAANA LETTER VAAVU -> 'v' */ + { 0x89, 0x6D }, /* THAANA LETTER MEEMU -> 'm' */ + { 0x8A, 0x66 }, /* THAANA LETTER FAAFU -> 'f' */ + { 0x8D, 0x6C }, /* THAANA LETTER LAAMU -> 'l' */ + { 0x8E, 0x67 }, /* THAANA LETTER GAAFU -> 'g' */ + { 0x90, 0x73 }, /* THAANA LETTER SEENU -> 's' */ + { 0x91, 0x64 }, /* THAANA LETTER DAVIYANI -> 'd' */ + { 0x92, 0x7A }, /* THAANA LETTER ZAVIYANI -> 'z' */ + { 0x93, 0x74 }, /* THAANA LETTER TAVIYANI -> 't' */ + { 0x94, 0x79 }, /* THAANA LETTER YAA -> 'y' */ + { 0x95, 0x70 }, /* THAANA LETTER PAVIYANI -> 'p' */ + { 0x96, 0x6A }, /* THAANA LETTER JAVIYANI -> 'j' */ + { 0x9C, 0x7A }, /* THAANA LETTER ZAA -> 'z' */ + { 0x9E, 0x73 }, /* THAANA LETTER SAADHU -> 's' */ + { 0x9F, 0x64 }, /* THAANA LETTER DAADHU -> 'd' */ + { 0xA0, 0x74 }, /* THAANA LETTER TO -> 't' */ + { 0xA1, 0x7A }, /* THAANA LETTER ZO -> 'z' */ + { 0xA2, 0x60 }, /* THAANA LETTER AINU -> '`' */ + { 0xA4, 0x71 }, /* THAANA LETTER QAAFU -> 'q' */ + { 0xA5, 0x77 }, /* THAANA LETTER WAAVU -> 'w' */ + { 0xA6, 0x61 }, /* THAANA ABAFILI -> 'a' */ + { 0xA8, 0x69 }, /* THAANA IBIFILI -> 'i' */ + { 0xAA, 0x75 }, /* THAANA UBUFILI -> 'u' */ + { 0xAC, 0x65 }, /* THAANA EBEFILI -> 'e' */ + { 0xAE, 0x6F }, /* THAANA OBOFILI -> 'o' */ + /* Entries for page 0x09 */ + { 0x01, 0x4E }, /* DEVANAGARI SIGN CANDRABINDU -> 'N' */ + { 0x02, 0x4E }, /* DEVANAGARI SIGN ANUSVARA -> 'N' */ + { 0x03, 0x48 }, /* DEVANAGARI SIGN VISARGA -> 'H' */ + { 0x05, 0x61 }, /* DEVANAGARI LETTER A -> 'a' */ + { 0x07, 0x69 }, /* DEVANAGARI LETTER I -> 'i' */ + { 0x09, 0x75 }, /* DEVANAGARI LETTER U -> 'u' */ + { 0x0B, 0x52 }, /* DEVANAGARI LETTER VOCALIC R -> 'R' */ + { 0x0C, 0x4C }, /* DEVANAGARI LETTER VOCALIC L -> 'L' */ + { 0x0E, 0x65 }, /* DEVANAGARI LETTER SHORT E -> 'e' */ + { 0x0F, 0x65 }, /* DEVANAGARI LETTER E -> 'e' */ + { 0x12, 0x6F }, /* DEVANAGARI LETTER SHORT O -> 'o' */ + { 0x13, 0x6F }, /* DEVANAGARI LETTER O -> 'o' */ + { 0x15, 0x6B }, /* DEVANAGARI LETTER KA -> 'k' */ + { 0x17, 0x67 }, /* DEVANAGARI LETTER GA -> 'g' */ + { 0x1A, 0x63 }, /* DEVANAGARI LETTER CA -> 'c' */ + { 0x1C, 0x6A }, /* DEVANAGARI LETTER JA -> 'j' */ + { 0x24, 0x74 }, /* DEVANAGARI LETTER TA -> 't' */ + { 0x26, 0x64 }, /* DEVANAGARI LETTER DA -> 'd' */ + { 0x28, 0x6E }, /* DEVANAGARI LETTER NA -> 'n' */ + { 0x2A, 0x70 }, /* DEVANAGARI LETTER PA -> 'p' */ + { 0x2C, 0x62 }, /* DEVANAGARI LETTER BA -> 'b' */ + { 0x2E, 0x6D }, /* DEVANAGARI LETTER MA -> 'm' */ + { 0x2F, 0x79 }, /* DEVANAGARI LETTER YA -> 'y' */ + { 0x30, 0x72 }, /* DEVANAGARI LETTER RA -> 'r' */ + { 0x32, 0x6C }, /* DEVANAGARI LETTER LA -> 'l' */ + { 0x33, 0x6C }, /* DEVANAGARI LETTER LLA -> 'l' */ + { 0x35, 0x76 }, /* DEVANAGARI LETTER VA -> 'v' */ + { 0x38, 0x73 }, /* DEVANAGARI LETTER SA -> 's' */ + { 0x39, 0x68 }, /* DEVANAGARI LETTER HA -> 'h' */ + { 0x3C, 0x27 }, /* DEVANAGARI SIGN NUKTA -> ''' */ + { 0x3D, 0x27 }, /* DEVANAGARI SIGN AVAGRAHA -> ''' */ + { 0x3F, 0x69 }, /* DEVANAGARI VOWEL SIGN I -> 'i' */ + { 0x41, 0x75 }, /* DEVANAGARI VOWEL SIGN U -> 'u' */ + { 0x43, 0x52 }, /* DEVANAGARI VOWEL SIGN VOCALIC R -> 'R' */ + { 0x46, 0x65 }, /* DEVANAGARI VOWEL SIGN SHORT E -> 'e' */ + { 0x47, 0x65 }, /* DEVANAGARI VOWEL SIGN E -> 'e' */ + { 0x4A, 0x6F }, /* DEVANAGARI VOWEL SIGN SHORT O -> 'o' */ + { 0x4B, 0x6F }, /* DEVANAGARI VOWEL SIGN O -> 'o' */ + { 0x51, 0x27 }, /* DEVANAGARI STRESS SIGN UDATTA -> ''' */ + { 0x52, 0x27 }, /* DEVANAGARI STRESS SIGN ANUDATTA -> ''' */ + { 0x53, 0x60 }, /* DEVANAGARI GRAVE ACCENT -> '`' */ + { 0x54, 0x27 }, /* DEVANAGARI ACUTE ACCENT -> ''' */ + { 0x58, 0x71 }, /* DEVANAGARI LETTER QA -> 'q' */ + { 0x5B, 0x7A }, /* DEVANAGARI LETTER ZA -> 'z' */ + { 0x5E, 0x66 }, /* DEVANAGARI LETTER FA -> 'f' */ + { 0x62, 0x4C }, /* DEVANAGARI VOWEL SIGN VOCALIC L -> 'L' */ + { 0x66, 0x30 }, /* DEVANAGARI DIGIT ZERO -> '0' */ + { 0x67, 0x31 }, /* DEVANAGARI DIGIT ONE -> '1' */ + { 0x68, 0x32 }, /* DEVANAGARI DIGIT TWO -> '2' */ + { 0x69, 0x33 }, /* DEVANAGARI DIGIT THREE -> '3' */ + { 0x6A, 0x34 }, /* DEVANAGARI DIGIT FOUR -> '4' */ + { 0x6B, 0x35 }, /* DEVANAGARI DIGIT FIVE -> '5' */ + { 0x6C, 0x36 }, /* DEVANAGARI DIGIT SIX -> '6' */ + { 0x6D, 0x37 }, /* DEVANAGARI DIGIT SEVEN -> '7' */ + { 0x6E, 0x38 }, /* DEVANAGARI DIGIT EIGHT -> '8' */ + { 0x6F, 0x39 }, /* DEVANAGARI DIGIT NINE -> '9' */ + { 0x70, 0x2E }, /* DEVANAGARI ABBREVIATION SIGN -> '.' */ + { 0x81, 0x4E }, /* BENGALI SIGN CANDRABINDU -> 'N' */ + { 0x82, 0x4E }, /* BENGALI SIGN ANUSVARA -> 'N' */ + { 0x83, 0x48 }, /* BENGALI SIGN VISARGA -> 'H' */ + { 0x85, 0x61 }, /* BENGALI LETTER A -> 'a' */ + { 0x87, 0x69 }, /* BENGALI LETTER I -> 'i' */ + { 0x89, 0x75 }, /* BENGALI LETTER U -> 'u' */ + { 0x8B, 0x52 }, /* BENGALI LETTER VOCALIC R -> 'R' */ + { 0x8F, 0x65 }, /* BENGALI LETTER E -> 'e' */ + { 0x93, 0x6F }, /* BENGALI LETTER O -> 'o' */ + { 0x95, 0x6B }, /* BENGALI LETTER KA -> 'k' */ + { 0x97, 0x67 }, /* BENGALI LETTER GA -> 'g' */ + { 0x9A, 0x63 }, /* BENGALI LETTER CA -> 'c' */ + { 0x9C, 0x6A }, /* BENGALI LETTER JA -> 'j' */ + { 0xA4, 0x74 }, /* BENGALI LETTER TA -> 't' */ + { 0xA6, 0x64 }, /* BENGALI LETTER DA -> 'd' */ + { 0xA8, 0x6E }, /* BENGALI LETTER NA -> 'n' */ + { 0xAA, 0x70 }, /* BENGALI LETTER PA -> 'p' */ + { 0xAC, 0x62 }, /* BENGALI LETTER BA -> 'b' */ + { 0xAE, 0x6D }, /* BENGALI LETTER MA -> 'm' */ + { 0xAF, 0x79 }, /* BENGALI LETTER YA -> 'y' */ + { 0xB0, 0x72 }, /* BENGALI LETTER RA -> 'r' */ + { 0xB2, 0x6C }, /* BENGALI LETTER LA -> 'l' */ + { 0xB8, 0x73 }, /* BENGALI LETTER SA -> 's' */ + { 0xB9, 0x68 }, /* BENGALI LETTER HA -> 'h' */ + { 0xBC, 0x27 }, /* BENGALI SIGN NUKTA -> ''' */ + { 0xBF, 0x69 }, /* BENGALI VOWEL SIGN I -> 'i' */ + { 0xC1, 0x75 }, /* BENGALI VOWEL SIGN U -> 'u' */ + { 0xC3, 0x52 }, /* BENGALI VOWEL SIGN VOCALIC R -> 'R' */ + { 0xC7, 0x65 }, /* BENGALI VOWEL SIGN E -> 'e' */ + { 0xCB, 0x6F }, /* BENGALI VOWEL SIGN O -> 'o' */ + { 0xD7, 0x2B }, /* BENGALI AU LENGTH MARK -> '+' */ + { 0xE2, 0x4C }, /* BENGALI VOWEL SIGN VOCALIC L -> 'L' */ + { 0xE6, 0x30 }, /* BENGALI DIGIT ZERO -> '0' */ + { 0xE7, 0x31 }, /* BENGALI DIGIT ONE -> '1' */ + { 0xE8, 0x32 }, /* BENGALI DIGIT TWO -> '2' */ + { 0xE9, 0x33 }, /* BENGALI DIGIT THREE -> '3' */ + { 0xEA, 0x34 }, /* BENGALI DIGIT FOUR -> '4' */ + { 0xEB, 0x35 }, /* BENGALI DIGIT FIVE -> '5' */ + { 0xEC, 0x36 }, /* BENGALI DIGIT SIX -> '6' */ + { 0xED, 0x37 }, /* BENGALI DIGIT SEVEN -> '7' */ + { 0xEE, 0x38 }, /* BENGALI DIGIT EIGHT -> '8' */ + { 0xEF, 0x39 }, /* BENGALI DIGIT NINE -> '9' */ + /* Entries for page 0x0A */ + { 0x02, 0x4E }, /* GURMUKHI SIGN BINDI -> 'N' */ + { 0x05, 0x61 }, /* GURMUKHI LETTER A -> 'a' */ + { 0x07, 0x69 }, /* GURMUKHI LETTER I -> 'i' */ + { 0x09, 0x75 }, /* GURMUKHI LETTER U -> 'u' */ + { 0x15, 0x6B }, /* GURMUKHI LETTER KA -> 'k' */ + { 0x17, 0x67 }, /* GURMUKHI LETTER GA -> 'g' */ + { 0x1A, 0x63 }, /* GURMUKHI LETTER CA -> 'c' */ + { 0x1C, 0x6A }, /* GURMUKHI LETTER JA -> 'j' */ + { 0x24, 0x74 }, /* GURMUKHI LETTER TA -> 't' */ + { 0x26, 0x64 }, /* GURMUKHI LETTER DA -> 'd' */ + { 0x28, 0x6E }, /* GURMUKHI LETTER NA -> 'n' */ + { 0x2A, 0x70 }, /* GURMUKHI LETTER PA -> 'p' */ + { 0x2C, 0x62 }, /* GURMUKHI LETTER BA -> 'b' */ + { 0x2E, 0x6D }, /* GURMUKHI LETTER MA -> 'm' */ + { 0x2F, 0x79 }, /* GURMUKHI LETTER YA -> 'y' */ + { 0x30, 0x72 }, /* GURMUKHI LETTER RA -> 'r' */ + { 0x32, 0x6C }, /* GURMUKHI LETTER LA -> 'l' */ + { 0x35, 0x76 }, /* GURMUKHI LETTER VA -> 'v' */ + { 0x38, 0x73 }, /* GURMUKHI LETTER SA -> 's' */ + { 0x39, 0x68 }, /* GURMUKHI LETTER HA -> 'h' */ + { 0x3C, 0x27 }, /* GURMUKHI SIGN NUKTA -> ''' */ + { 0x3F, 0x69 }, /* GURMUKHI VOWEL SIGN I -> 'i' */ + { 0x41, 0x75 }, /* GURMUKHI VOWEL SIGN U -> 'u' */ + { 0x5B, 0x7A }, /* GURMUKHI LETTER ZA -> 'z' */ + { 0x5E, 0x66 }, /* GURMUKHI LETTER FA -> 'f' */ + { 0x66, 0x30 }, /* GURMUKHI DIGIT ZERO -> '0' */ + { 0x67, 0x31 }, /* GURMUKHI DIGIT ONE -> '1' */ + { 0x68, 0x32 }, /* GURMUKHI DIGIT TWO -> '2' */ + { 0x69, 0x33 }, /* GURMUKHI DIGIT THREE -> '3' */ + { 0x6A, 0x34 }, /* GURMUKHI DIGIT FOUR -> '4' */ + { 0x6B, 0x35 }, /* GURMUKHI DIGIT FIVE -> '5' */ + { 0x6C, 0x36 }, /* GURMUKHI DIGIT SIX -> '6' */ + { 0x6D, 0x37 }, /* GURMUKHI DIGIT SEVEN -> '7' */ + { 0x6E, 0x38 }, /* GURMUKHI DIGIT EIGHT -> '8' */ + { 0x6F, 0x39 }, /* GURMUKHI DIGIT NINE -> '9' */ + { 0x70, 0x4E }, /* GURMUKHI TIPPI -> 'N' */ + { 0x71, 0x48 }, /* GURMUKHI ADDAK -> 'H' */ + { 0x81, 0x4E }, /* GUJARATI SIGN CANDRABINDU -> 'N' */ + { 0x82, 0x4E }, /* GUJARATI SIGN ANUSVARA -> 'N' */ + { 0x83, 0x48 }, /* GUJARATI SIGN VISARGA -> 'H' */ + { 0x85, 0x61 }, /* GUJARATI LETTER A -> 'a' */ + { 0x87, 0x69 }, /* GUJARATI LETTER I -> 'i' */ + { 0x89, 0x75 }, /* GUJARATI LETTER U -> 'u' */ + { 0x8B, 0x52 }, /* GUJARATI LETTER VOCALIC R -> 'R' */ + { 0x8F, 0x65 }, /* GUJARATI LETTER E -> 'e' */ + { 0x93, 0x6F }, /* GUJARATI LETTER O -> 'o' */ + { 0x95, 0x6B }, /* GUJARATI LETTER KA -> 'k' */ + { 0x97, 0x67 }, /* GUJARATI LETTER GA -> 'g' */ + { 0x9A, 0x63 }, /* GUJARATI LETTER CA -> 'c' */ + { 0x9C, 0x6A }, /* GUJARATI LETTER JA -> 'j' */ + { 0xA4, 0x74 }, /* GUJARATI LETTER TA -> 't' */ + { 0xA6, 0x64 }, /* GUJARATI LETTER DA -> 'd' */ + { 0xA8, 0x6E }, /* GUJARATI LETTER NA -> 'n' */ + { 0xAA, 0x70 }, /* GUJARATI LETTER PA -> 'p' */ + { 0xAC, 0x62 }, /* GUJARATI LETTER BA -> 'b' */ + { 0xAE, 0x6D }, /* GUJARATI LETTER MA -> 'm' */ + { 0xB0, 0x72 }, /* GUJARATI LETTER RA -> 'r' */ + { 0xB2, 0x6C }, /* GUJARATI LETTER LA -> 'l' */ + { 0xB5, 0x76 }, /* GUJARATI LETTER VA -> 'v' */ + { 0xB8, 0x73 }, /* GUJARATI LETTER SA -> 's' */ + { 0xB9, 0x68 }, /* GUJARATI LETTER HA -> 'h' */ + { 0xBC, 0x27 }, /* GUJARATI SIGN NUKTA -> ''' */ + { 0xBD, 0x27 }, /* GUJARATI SIGN AVAGRAHA -> ''' */ + { 0xBF, 0x69 }, /* GUJARATI VOWEL SIGN I -> 'i' */ + { 0xC1, 0x75 }, /* GUJARATI VOWEL SIGN U -> 'u' */ + { 0xC3, 0x52 }, /* GUJARATI VOWEL SIGN VOCALIC R -> 'R' */ + { 0xC7, 0x65 }, /* GUJARATI VOWEL SIGN E -> 'e' */ + { 0xCB, 0x6F }, /* GUJARATI VOWEL SIGN O -> 'o' */ + { 0xE6, 0x30 }, /* GUJARATI DIGIT ZERO -> '0' */ + { 0xE7, 0x31 }, /* GUJARATI DIGIT ONE -> '1' */ + { 0xE8, 0x32 }, /* GUJARATI DIGIT TWO -> '2' */ + { 0xE9, 0x33 }, /* GUJARATI DIGIT THREE -> '3' */ + { 0xEA, 0x34 }, /* GUJARATI DIGIT FOUR -> '4' */ + { 0xEB, 0x35 }, /* GUJARATI DIGIT FIVE -> '5' */ + { 0xEC, 0x36 }, /* GUJARATI DIGIT SIX -> '6' */ + { 0xED, 0x37 }, /* GUJARATI DIGIT SEVEN -> '7' */ + { 0xEE, 0x38 }, /* GUJARATI DIGIT EIGHT -> '8' */ + { 0xEF, 0x39 }, /* GUJARATI DIGIT NINE -> '9' */ + /* Entries for page 0x0B */ + { 0x01, 0x4E }, /* ORIYA SIGN CANDRABINDU -> 'N' */ + { 0x02, 0x4E }, /* ORIYA SIGN ANUSVARA -> 'N' */ + { 0x03, 0x48 }, /* ORIYA SIGN VISARGA -> 'H' */ + { 0x05, 0x61 }, /* ORIYA LETTER A -> 'a' */ + { 0x07, 0x69 }, /* ORIYA LETTER I -> 'i' */ + { 0x09, 0x75 }, /* ORIYA LETTER U -> 'u' */ + { 0x0B, 0x52 }, /* ORIYA LETTER VOCALIC R -> 'R' */ + { 0x0C, 0x4C }, /* ORIYA LETTER VOCALIC L -> 'L' */ + { 0x0F, 0x65 }, /* ORIYA LETTER E -> 'e' */ + { 0x13, 0x6F }, /* ORIYA LETTER O -> 'o' */ + { 0x15, 0x6B }, /* ORIYA LETTER KA -> 'k' */ + { 0x17, 0x67 }, /* ORIYA LETTER GA -> 'g' */ + { 0x1A, 0x63 }, /* ORIYA LETTER CA -> 'c' */ + { 0x1C, 0x6A }, /* ORIYA LETTER JA -> 'j' */ + { 0x24, 0x74 }, /* ORIYA LETTER TA -> 't' */ + { 0x26, 0x64 }, /* ORIYA LETTER DA -> 'd' */ + { 0x28, 0x6E }, /* ORIYA LETTER NA -> 'n' */ + { 0x2A, 0x70 }, /* ORIYA LETTER PA -> 'p' */ + { 0x2C, 0x62 }, /* ORIYA LETTER BA -> 'b' */ + { 0x2E, 0x6D }, /* ORIYA LETTER MA -> 'm' */ + { 0x2F, 0x79 }, /* ORIYA LETTER YA -> 'y' */ + { 0x30, 0x72 }, /* ORIYA LETTER RA -> 'r' */ + { 0x32, 0x6C }, /* ORIYA LETTER LA -> 'l' */ + { 0x38, 0x73 }, /* ORIYA LETTER SA -> 's' */ + { 0x39, 0x68 }, /* ORIYA LETTER HA -> 'h' */ + { 0x3C, 0x27 }, /* ORIYA SIGN NUKTA -> ''' */ + { 0x3D, 0x27 }, /* ORIYA SIGN AVAGRAHA -> ''' */ + { 0x3F, 0x69 }, /* ORIYA VOWEL SIGN I -> 'i' */ + { 0x41, 0x75 }, /* ORIYA VOWEL SIGN U -> 'u' */ + { 0x43, 0x52 }, /* ORIYA VOWEL SIGN VOCALIC R -> 'R' */ + { 0x47, 0x65 }, /* ORIYA VOWEL SIGN E -> 'e' */ + { 0x4B, 0x6F }, /* ORIYA VOWEL SIGN O -> 'o' */ + { 0x56, 0x2B }, /* ORIYA AI LENGTH MARK -> '+' */ + { 0x57, 0x2B }, /* ORIYA AU LENGTH MARK -> '+' */ + { 0x66, 0x30 }, /* ORIYA DIGIT ZERO -> '0' */ + { 0x67, 0x31 }, /* ORIYA DIGIT ONE -> '1' */ + { 0x68, 0x32 }, /* ORIYA DIGIT TWO -> '2' */ + { 0x69, 0x33 }, /* ORIYA DIGIT THREE -> '3' */ + { 0x6A, 0x34 }, /* ORIYA DIGIT FOUR -> '4' */ + { 0x6B, 0x35 }, /* ORIYA DIGIT FIVE -> '5' */ + { 0x6C, 0x36 }, /* ORIYA DIGIT SIX -> '6' */ + { 0x6D, 0x37 }, /* ORIYA DIGIT SEVEN -> '7' */ + { 0x6E, 0x38 }, /* ORIYA DIGIT EIGHT -> '8' */ + { 0x6F, 0x39 }, /* ORIYA DIGIT NINE -> '9' */ + { 0x82, 0x4E }, /* TAMIL SIGN ANUSVARA -> 'N' */ + { 0x83, 0x48 }, /* TAMIL SIGN VISARGA -> 'H' */ + { 0x85, 0x61 }, /* TAMIL LETTER A -> 'a' */ + { 0x87, 0x69 }, /* TAMIL LETTER I -> 'i' */ + { 0x89, 0x75 }, /* TAMIL LETTER U -> 'u' */ + { 0x8E, 0x65 }, /* TAMIL LETTER E -> 'e' */ + { 0x92, 0x6F }, /* TAMIL LETTER O -> 'o' */ + { 0x95, 0x6B }, /* TAMIL LETTER KA -> 'k' */ + { 0x9A, 0x63 }, /* TAMIL LETTER CA -> 'c' */ + { 0x9C, 0x6A }, /* TAMIL LETTER JA -> 'j' */ + { 0xA4, 0x74 }, /* TAMIL LETTER TA -> 't' */ + { 0xA8, 0x6E }, /* TAMIL LETTER NA -> 'n' */ + { 0xAA, 0x70 }, /* TAMIL LETTER PA -> 'p' */ + { 0xAE, 0x6D }, /* TAMIL LETTER MA -> 'm' */ + { 0xAF, 0x79 }, /* TAMIL LETTER YA -> 'y' */ + { 0xB0, 0x72 }, /* TAMIL LETTER RA -> 'r' */ + { 0xB2, 0x6C }, /* TAMIL LETTER LA -> 'l' */ + { 0xB5, 0x76 }, /* TAMIL LETTER VA -> 'v' */ + { 0xB8, 0x73 }, /* TAMIL LETTER SA -> 's' */ + { 0xB9, 0x68 }, /* TAMIL LETTER HA -> 'h' */ + { 0xBF, 0x69 }, /* TAMIL VOWEL SIGN I -> 'i' */ + { 0xC1, 0x75 }, /* TAMIL VOWEL SIGN U -> 'u' */ + { 0xC6, 0x65 }, /* TAMIL VOWEL SIGN E -> 'e' */ + { 0xCA, 0x6F }, /* TAMIL VOWEL SIGN O -> 'o' */ + { 0xD7, 0x2B }, /* TAMIL AU LENGTH MARK -> '+' */ + { 0xE6, 0x30 }, /* TAMIL DIGIT ZERO -> '0' */ + { 0xE7, 0x31 }, /* TAMIL DIGIT ONE -> '1' */ + { 0xE8, 0x32 }, /* TAMIL DIGIT TWO -> '2' */ + { 0xE9, 0x33 }, /* TAMIL DIGIT THREE -> '3' */ + { 0xEA, 0x34 }, /* TAMIL DIGIT FOUR -> '4' */ + { 0xEB, 0x35 }, /* TAMIL DIGIT FIVE -> '5' */ + { 0xEC, 0x36 }, /* TAMIL DIGIT SIX -> '6' */ + { 0xED, 0x37 }, /* TAMIL DIGIT SEVEN -> '7' */ + { 0xEE, 0x38 }, /* TAMIL DIGIT EIGHT -> '8' */ + { 0xEF, 0x39 }, /* TAMIL DIGIT NINE -> '9' */ + /* Entries for page 0x0C */ + { 0x01, 0x4E }, /* TELUGU SIGN CANDRABINDU -> 'N' */ + { 0x02, 0x4E }, /* TELUGU SIGN ANUSVARA -> 'N' */ + { 0x03, 0x48 }, /* TELUGU SIGN VISARGA -> 'H' */ + { 0x05, 0x61 }, /* TELUGU LETTER A -> 'a' */ + { 0x07, 0x69 }, /* TELUGU LETTER I -> 'i' */ + { 0x09, 0x75 }, /* TELUGU LETTER U -> 'u' */ + { 0x0B, 0x52 }, /* TELUGU LETTER VOCALIC R -> 'R' */ + { 0x0C, 0x4C }, /* TELUGU LETTER VOCALIC L -> 'L' */ + { 0x0E, 0x65 }, /* TELUGU LETTER E -> 'e' */ + { 0x12, 0x6F }, /* TELUGU LETTER O -> 'o' */ + { 0x15, 0x6B }, /* TELUGU LETTER KA -> 'k' */ + { 0x17, 0x67 }, /* TELUGU LETTER GA -> 'g' */ + { 0x1A, 0x63 }, /* TELUGU LETTER CA -> 'c' */ + { 0x1C, 0x6A }, /* TELUGU LETTER JA -> 'j' */ + { 0x24, 0x74 }, /* TELUGU LETTER TA -> 't' */ + { 0x26, 0x64 }, /* TELUGU LETTER DA -> 'd' */ + { 0x28, 0x6E }, /* TELUGU LETTER NA -> 'n' */ + { 0x2A, 0x70 }, /* TELUGU LETTER PA -> 'p' */ + { 0x2C, 0x62 }, /* TELUGU LETTER BA -> 'b' */ + { 0x2E, 0x6D }, /* TELUGU LETTER MA -> 'm' */ + { 0x2F, 0x79 }, /* TELUGU LETTER YA -> 'y' */ + { 0x30, 0x72 }, /* TELUGU LETTER RA -> 'r' */ + { 0x32, 0x6C }, /* TELUGU LETTER LA -> 'l' */ + { 0x35, 0x76 }, /* TELUGU LETTER VA -> 'v' */ + { 0x38, 0x73 }, /* TELUGU LETTER SA -> 's' */ + { 0x39, 0x68 }, /* TELUGU LETTER HA -> 'h' */ + { 0x3F, 0x69 }, /* TELUGU VOWEL SIGN I -> 'i' */ + { 0x41, 0x75 }, /* TELUGU VOWEL SIGN U -> 'u' */ + { 0x43, 0x52 }, /* TELUGU VOWEL SIGN VOCALIC R -> 'R' */ + { 0x46, 0x65 }, /* TELUGU VOWEL SIGN E -> 'e' */ + { 0x4A, 0x6F }, /* TELUGU VOWEL SIGN O -> 'o' */ + { 0x55, 0x2B }, /* TELUGU LENGTH MARK -> '+' */ + { 0x56, 0x2B }, /* TELUGU AI LENGTH MARK -> '+' */ + { 0x66, 0x30 }, /* TELUGU DIGIT ZERO -> '0' */ + { 0x67, 0x31 }, /* TELUGU DIGIT ONE -> '1' */ + { 0x68, 0x32 }, /* TELUGU DIGIT TWO -> '2' */ + { 0x69, 0x33 }, /* TELUGU DIGIT THREE -> '3' */ + { 0x6A, 0x34 }, /* TELUGU DIGIT FOUR -> '4' */ + { 0x6B, 0x35 }, /* TELUGU DIGIT FIVE -> '5' */ + { 0x6C, 0x36 }, /* TELUGU DIGIT SIX -> '6' */ + { 0x6D, 0x37 }, /* TELUGU DIGIT SEVEN -> '7' */ + { 0x6E, 0x38 }, /* TELUGU DIGIT EIGHT -> '8' */ + { 0x6F, 0x39 }, /* TELUGU DIGIT NINE -> '9' */ + { 0x82, 0x4E }, /* KANNADA SIGN ANUSVARA -> 'N' */ + { 0x83, 0x48 }, /* KANNADA SIGN VISARGA -> 'H' */ + { 0x85, 0x61 }, /* KANNADA LETTER A -> 'a' */ + { 0x87, 0x69 }, /* KANNADA LETTER I -> 'i' */ + { 0x89, 0x75 }, /* KANNADA LETTER U -> 'u' */ + { 0x8B, 0x52 }, /* KANNADA LETTER VOCALIC R -> 'R' */ + { 0x8C, 0x4C }, /* KANNADA LETTER VOCALIC L -> 'L' */ + { 0x8E, 0x65 }, /* KANNADA LETTER E -> 'e' */ + { 0x92, 0x6F }, /* KANNADA LETTER O -> 'o' */ + { 0x95, 0x6B }, /* KANNADA LETTER KA -> 'k' */ + { 0x97, 0x67 }, /* KANNADA LETTER GA -> 'g' */ + { 0x9A, 0x63 }, /* KANNADA LETTER CA -> 'c' */ + { 0x9C, 0x6A }, /* KANNADA LETTER JA -> 'j' */ + { 0xA4, 0x74 }, /* KANNADA LETTER TA -> 't' */ + { 0xA6, 0x64 }, /* KANNADA LETTER DA -> 'd' */ + { 0xA8, 0x6E }, /* KANNADA LETTER NA -> 'n' */ + { 0xAA, 0x70 }, /* KANNADA LETTER PA -> 'p' */ + { 0xAC, 0x62 }, /* KANNADA LETTER BA -> 'b' */ + { 0xAE, 0x6D }, /* KANNADA LETTER MA -> 'm' */ + { 0xAF, 0x79 }, /* KANNADA LETTER YA -> 'y' */ + { 0xB0, 0x72 }, /* KANNADA LETTER RA -> 'r' */ + { 0xB2, 0x6C }, /* KANNADA LETTER LA -> 'l' */ + { 0xB5, 0x76 }, /* KANNADA LETTER VA -> 'v' */ + { 0xB8, 0x73 }, /* KANNADA LETTER SA -> 's' */ + { 0xB9, 0x68 }, /* KANNADA LETTER HA -> 'h' */ + { 0xBF, 0x69 }, /* KANNADA VOWEL SIGN I -> 'i' */ + { 0xC1, 0x75 }, /* KANNADA VOWEL SIGN U -> 'u' */ + { 0xC3, 0x52 }, /* KANNADA VOWEL SIGN VOCALIC R -> 'R' */ + { 0xC6, 0x65 }, /* KANNADA VOWEL SIGN E -> 'e' */ + { 0xCA, 0x6F }, /* KANNADA VOWEL SIGN O -> 'o' */ + { 0xD5, 0x2B }, /* KANNADA LENGTH MARK -> '+' */ + { 0xD6, 0x2B }, /* KANNADA AI LENGTH MARK -> '+' */ + { 0xE6, 0x30 }, /* KANNADA DIGIT ZERO -> '0' */ + { 0xE7, 0x31 }, /* KANNADA DIGIT ONE -> '1' */ + { 0xE8, 0x32 }, /* KANNADA DIGIT TWO -> '2' */ + { 0xE9, 0x33 }, /* KANNADA DIGIT THREE -> '3' */ + { 0xEA, 0x34 }, /* KANNADA DIGIT FOUR -> '4' */ + { 0xEB, 0x35 }, /* KANNADA DIGIT FIVE -> '5' */ + { 0xEC, 0x36 }, /* KANNADA DIGIT SIX -> '6' */ + { 0xED, 0x37 }, /* KANNADA DIGIT SEVEN -> '7' */ + { 0xEE, 0x38 }, /* KANNADA DIGIT EIGHT -> '8' */ + { 0xEF, 0x39 }, /* KANNADA DIGIT NINE -> '9' */ + /* Entries for page 0x0D */ + { 0x02, 0x4E }, /* MALAYALAM SIGN ANUSVARA -> 'N' */ + { 0x03, 0x48 }, /* MALAYALAM SIGN VISARGA -> 'H' */ + { 0x05, 0x61 }, /* MALAYALAM LETTER A -> 'a' */ + { 0x07, 0x69 }, /* MALAYALAM LETTER I -> 'i' */ + { 0x09, 0x75 }, /* MALAYALAM LETTER U -> 'u' */ + { 0x0B, 0x52 }, /* MALAYALAM LETTER VOCALIC R -> 'R' */ + { 0x0C, 0x4C }, /* MALAYALAM LETTER VOCALIC L -> 'L' */ + { 0x0E, 0x65 }, /* MALAYALAM LETTER E -> 'e' */ + { 0x12, 0x6F }, /* MALAYALAM LETTER O -> 'o' */ + { 0x15, 0x6B }, /* MALAYALAM LETTER KA -> 'k' */ + { 0x17, 0x67 }, /* MALAYALAM LETTER GA -> 'g' */ + { 0x1A, 0x63 }, /* MALAYALAM LETTER CA -> 'c' */ + { 0x1C, 0x6A }, /* MALAYALAM LETTER JA -> 'j' */ + { 0x24, 0x74 }, /* MALAYALAM LETTER TA -> 't' */ + { 0x26, 0x64 }, /* MALAYALAM LETTER DA -> 'd' */ + { 0x28, 0x6E }, /* MALAYALAM LETTER NA -> 'n' */ + { 0x2A, 0x70 }, /* MALAYALAM LETTER PA -> 'p' */ + { 0x2C, 0x62 }, /* MALAYALAM LETTER BA -> 'b' */ + { 0x2E, 0x6D }, /* MALAYALAM LETTER MA -> 'm' */ + { 0x2F, 0x79 }, /* MALAYALAM LETTER YA -> 'y' */ + { 0x30, 0x72 }, /* MALAYALAM LETTER RA -> 'r' */ + { 0x32, 0x6C }, /* MALAYALAM LETTER LA -> 'l' */ + { 0x35, 0x76 }, /* MALAYALAM LETTER VA -> 'v' */ + { 0x38, 0x73 }, /* MALAYALAM LETTER SA -> 's' */ + { 0x39, 0x68 }, /* MALAYALAM LETTER HA -> 'h' */ + { 0x3F, 0x69 }, /* MALAYALAM VOWEL SIGN I -> 'i' */ + { 0x41, 0x75 }, /* MALAYALAM VOWEL SIGN U -> 'u' */ + { 0x43, 0x52 }, /* MALAYALAM VOWEL SIGN VOCALIC R -> 'R' */ + { 0x46, 0x65 }, /* MALAYALAM VOWEL SIGN E -> 'e' */ + { 0x4A, 0x6F }, /* MALAYALAM VOWEL SIGN O -> 'o' */ + { 0x57, 0x2B }, /* MALAYALAM AU LENGTH MARK -> '+' */ + { 0x66, 0x30 }, /* MALAYALAM DIGIT ZERO -> '0' */ + { 0x67, 0x31 }, /* MALAYALAM DIGIT ONE -> '1' */ + { 0x68, 0x32 }, /* MALAYALAM DIGIT TWO -> '2' */ + { 0x69, 0x33 }, /* MALAYALAM DIGIT THREE -> '3' */ + { 0x6A, 0x34 }, /* MALAYALAM DIGIT FOUR -> '4' */ + { 0x6B, 0x35 }, /* MALAYALAM DIGIT FIVE -> '5' */ + { 0x6C, 0x36 }, /* MALAYALAM DIGIT SIX -> '6' */ + { 0x6D, 0x37 }, /* MALAYALAM DIGIT SEVEN -> '7' */ + { 0x6E, 0x38 }, /* MALAYALAM DIGIT EIGHT -> '8' */ + { 0x6F, 0x39 }, /* MALAYALAM DIGIT NINE -> '9' */ + { 0x82, 0x4E }, /* SINHALA SIGN ANUSVARAYA -> 'N' */ + { 0x83, 0x48 }, /* SINHALA SIGN VISARGAYA -> 'H' */ + { 0x85, 0x61 }, /* SINHALA LETTER AYANNA -> 'a' */ + { 0x89, 0x69 }, /* SINHALA LETTER IYANNA -> 'i' */ + { 0x8B, 0x75 }, /* SINHALA LETTER UYANNA -> 'u' */ + { 0x8D, 0x52 }, /* SINHALA LETTER IRUYANNA -> 'R' */ + { 0x8F, 0x4C }, /* SINHALA LETTER ILUYANNA -> 'L' */ + { 0x91, 0x65 }, /* SINHALA LETTER EYANNA -> 'e' */ + { 0x94, 0x6F }, /* SINHALA LETTER OYANNA -> 'o' */ + { 0x9A, 0x6B }, /* SINHALA LETTER ALPAPRAANA KAYANNA -> 'k' */ + { 0x9C, 0x67 }, /* SINHALA LETTER ALPAPRAANA GAYANNA -> 'g' */ + { 0xA0, 0x63 }, /* SINHALA LETTER ALPAPRAANA CAYANNA -> 'c' */ + { 0xA2, 0x6A }, /* SINHALA LETTER ALPAPRAANA JAYANNA -> 'j' */ + { 0xAD, 0x74 }, /* SINHALA LETTER ALPAPRAANA TAYANNA -> 't' */ + { 0xAF, 0x64 }, /* SINHALA LETTER ALPAPRAANA DAYANNA -> 'd' */ + { 0xB1, 0x6E }, /* SINHALA LETTER DANTAJA NAYANNA -> 'n' */ + { 0xB4, 0x70 }, /* SINHALA LETTER ALPAPRAANA PAYANNA -> 'p' */ + { 0xB6, 0x62 }, /* SINHALA LETTER ALPAPRAANA BAYANNA -> 'b' */ + { 0xB8, 0x6D }, /* SINHALA LETTER MAYANNA -> 'm' */ + { 0xBA, 0x79 }, /* SINHALA LETTER YAYANNA -> 'y' */ + { 0xBB, 0x72 }, /* SINHALA LETTER RAYANNA -> 'r' */ + { 0xBD, 0x6C }, /* SINHALA LETTER DANTAJA LAYANNA -> 'l' */ + { 0xC0, 0x76 }, /* SINHALA LETTER VAYANNA -> 'v' */ + { 0xC3, 0x73 }, /* SINHALA LETTER DANTAJA SAYANNA -> 's' */ + { 0xC4, 0x68 }, /* SINHALA LETTER HAYANNA -> 'h' */ + { 0xC6, 0x66 }, /* SINHALA LETTER FAYANNA -> 'f' */ + { 0xD2, 0x69 }, /* SINHALA VOWEL SIGN KETTI IS-PILLA -> 'i' */ + { 0xD4, 0x75 }, /* SINHALA VOWEL SIGN KETTI PAA-PILLA -> 'u' */ + { 0xD8, 0x52 }, /* SINHALA VOWEL SIGN GAETTA-PILLA -> 'R' */ + { 0xD9, 0x65 }, /* SINHALA VOWEL SIGN KOMBUVA -> 'e' */ + { 0xDC, 0x6F }, /* SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA -> 'o' */ + { 0xDF, 0x4C }, /* SINHALA VOWEL SIGN GAYANUKITTA -> 'L' */ + /* Entries for page 0x0E */ + { 0x01, 0x6B }, /* THAI CHARACTER KO KAI -> 'k' */ + { 0x0D, 0x79 }, /* THAI CHARACTER YO YING -> 'y' */ + { 0x0E, 0x64 }, /* THAI CHARACTER DO CHADA -> 'd' */ + { 0x0F, 0x74 }, /* THAI CHARACTER TO PATAK -> 't' */ + { 0x13, 0x6E }, /* THAI CHARACTER NO NEN -> 'n' */ + { 0x14, 0x64 }, /* THAI CHARACTER DO DEK -> 'd' */ + { 0x15, 0x74 }, /* THAI CHARACTER TO TAO -> 't' */ + { 0x19, 0x6E }, /* THAI CHARACTER NO NU -> 'n' */ + { 0x1A, 0x62 }, /* THAI CHARACTER BO BAIMAI -> 'b' */ + { 0x1B, 0x70 }, /* THAI CHARACTER PO PLA -> 'p' */ + { 0x1D, 0x66 }, /* THAI CHARACTER FO FA -> 'f' */ + { 0x1F, 0x66 }, /* THAI CHARACTER FO FAN -> 'f' */ + { 0x21, 0x6D }, /* THAI CHARACTER MO MA -> 'm' */ + { 0x22, 0x79 }, /* THAI CHARACTER YO YAK -> 'y' */ + { 0x23, 0x72 }, /* THAI CHARACTER RO RUA -> 'r' */ + { 0x24, 0x52 }, /* THAI CHARACTER RU -> 'R' */ + { 0x25, 0x6C }, /* THAI CHARACTER LO LING -> 'l' */ + { 0x26, 0x4C }, /* THAI CHARACTER LU -> 'L' */ + { 0x27, 0x77 }, /* THAI CHARACTER WO WAEN -> 'w' */ + { 0x28, 0x00 }, /* THAI CHARACTER SO SALA -> ... */ + { 0x2A, 0x73 }, /* THAI CHARACTER SO SUA -> 's' */ + { 0x2B, 0x68 }, /* THAI CHARACTER HO HIP -> 'h' */ + { 0x2C, 0x6C }, /* THAI CHARACTER LO CHULA -> 'l' */ + { 0x2D, 0x60 }, /* THAI CHARACTER O ANG -> '`' */ + { 0x2E, 0x68 }, /* THAI CHARACTER HO NOKHUK -> 'h' */ + { 0x2F, 0x7E }, /* THAI CHARACTER PAIYANNOI -> '~' */ + { 0x30, 0x61 }, /* THAI CHARACTER SARA A -> 'a' */ + { 0x31, 0x61 }, /* THAI CHARACTER MAI HAN-AKAT -> 'a' */ + { 0x34, 0x69 }, /* THAI CHARACTER SARA I -> 'i' */ + { 0x38, 0x75 }, /* THAI CHARACTER SARA U -> 'u' */ + { 0x3A, 0x27 }, /* THAI CHARACTER PHINTHU -> ''' */ + { 0x40, 0x65 }, /* THAI CHARACTER SARA E -> 'e' */ + { 0x42, 0x6F }, /* THAI CHARACTER SARA O -> 'o' */ + { 0x46, 0x2B }, /* THAI CHARACTER MAIYAMOK -> '+' */ + { 0x4D, 0x4D }, /* THAI CHARACTER NIKHAHIT -> 'M' */ + { 0x50, 0x30 }, /* THAI DIGIT ZERO -> '0' */ + { 0x51, 0x31 }, /* THAI DIGIT ONE -> '1' */ + { 0x52, 0x32 }, /* THAI DIGIT TWO -> '2' */ + { 0x53, 0x33 }, /* THAI DIGIT THREE -> '3' */ + { 0x54, 0x34 }, /* THAI DIGIT FOUR -> '4' */ + { 0x55, 0x35 }, /* THAI DIGIT FIVE -> '5' */ + { 0x56, 0x36 }, /* THAI DIGIT SIX -> '6' */ + { 0x57, 0x37 }, /* THAI DIGIT SEVEN -> '7' */ + { 0x58, 0x38 }, /* THAI DIGIT EIGHT -> '8' */ + { 0x59, 0x39 }, /* THAI DIGIT NINE -> '9' */ + { 0x81, 0x6B }, /* LAO LETTER KO -> 'k' */ + { 0x8A, 0x73 }, /* LAO LETTER SO TAM -> 's' */ + { 0x94, 0x64 }, /* LAO LETTER DO -> 'd' */ + { 0x95, 0x68 }, /* LAO LETTER TO -> 'h' */ + { 0x99, 0x6E }, /* LAO LETTER NO -> 'n' */ + { 0x9A, 0x62 }, /* LAO LETTER BO -> 'b' */ + { 0x9B, 0x70 }, /* LAO LETTER PO -> 'p' */ + { 0x9D, 0x66 }, /* LAO LETTER FO TAM -> 'f' */ + { 0x9F, 0x66 }, /* LAO LETTER FO SUNG -> 'f' */ + { 0xA1, 0x6D }, /* LAO LETTER MO -> 'm' */ + { 0xA2, 0x79 }, /* LAO LETTER YO -> 'y' */ + { 0xA3, 0x72 }, /* LAO LETTER LO LING -> 'r' */ + { 0xA5, 0x6C }, /* LAO LETTER LO LOOT -> 'l' */ + { 0xA7, 0x77 }, /* LAO LETTER WO -> 'w' */ + { 0xAA, 0x73 }, /* LAO LETTER SO SUNG -> 's' */ + { 0xAB, 0x68 }, /* LAO LETTER HO SUNG -> 'h' */ + { 0xAD, 0x60 }, /* LAO LETTER O -> '`' */ + { 0xAF, 0x7E }, /* LAO ELLIPSIS -> '~' */ + { 0xB0, 0x61 }, /* LAO VOWEL SIGN A -> 'a' */ + { 0xB4, 0x69 }, /* LAO VOWEL SIGN I -> 'i' */ + { 0xB6, 0x79 }, /* LAO VOWEL SIGN Y -> 'y' */ + { 0xB8, 0x75 }, /* LAO VOWEL SIGN U -> 'u' */ + { 0xBB, 0x6F }, /* LAO VOWEL SIGN MAI KON -> 'o' */ + { 0xBC, 0x6C }, /* LAO SEMIVOWEL SIGN LO -> 'l' */ + { 0xC0, 0x65 }, /* LAO VOWEL SIGN E -> 'e' */ + { 0xC2, 0x6F }, /* LAO VOWEL SIGN O -> 'o' */ + { 0xC6, 0x2B }, /* LAO KO LA -> '+' */ + { 0xCD, 0x4D }, /* LAO NIGGAHITA -> 'M' */ + { 0xD0, 0x30 }, /* LAO DIGIT ZERO -> '0' */ + { 0xD1, 0x31 }, /* LAO DIGIT ONE -> '1' */ + { 0xD2, 0x32 }, /* LAO DIGIT TWO -> '2' */ + { 0xD3, 0x33 }, /* LAO DIGIT THREE -> '3' */ + { 0xD4, 0x34 }, /* LAO DIGIT FOUR -> '4' */ + { 0xD5, 0x35 }, /* LAO DIGIT FIVE -> '5' */ + { 0xD6, 0x36 }, /* LAO DIGIT SIX -> '6' */ + { 0xD7, 0x37 }, /* LAO DIGIT SEVEN -> '7' */ + { 0xD8, 0x38 }, /* LAO DIGIT EIGHT -> '8' */ + { 0xD9, 0x39 }, /* LAO DIGIT NINE -> '9' */ + /* Entries for page 0x0F */ + { 0x0B, 0x2D }, /* TIBETAN MARK INTERSYLLABIC TSHEG -> '-' */ + { 0x20, 0x30 }, /* TIBETAN DIGIT ZERO -> '0' */ + { 0x21, 0x31 }, /* TIBETAN DIGIT ONE -> '1' */ + { 0x22, 0x32 }, /* TIBETAN DIGIT TWO -> '2' */ + { 0x23, 0x33 }, /* TIBETAN DIGIT THREE -> '3' */ + { 0x24, 0x34 }, /* TIBETAN DIGIT FOUR -> '4' */ + { 0x25, 0x35 }, /* TIBETAN DIGIT FIVE -> '5' */ + { 0x26, 0x36 }, /* TIBETAN DIGIT SIX -> '6' */ + { 0x27, 0x37 }, /* TIBETAN DIGIT SEVEN -> '7' */ + { 0x28, 0x38 }, /* TIBETAN DIGIT EIGHT -> '8' */ + { 0x29, 0x39 }, /* TIBETAN DIGIT NINE -> '9' */ + { 0x34, 0x2B }, /* TIBETAN MARK BSDUS RTAGS -> '+' */ + { 0x35, 0x2A }, /* TIBETAN MARK NGAS BZUNG NYI ZLA -> '*' */ + { 0x36, 0x5E }, /* TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN -> '^' */ + { 0x37, 0x5F }, /* TIBETAN MARK NGAS BZUNG SGOR RTAGS -> '_' */ + { 0x39, 0x7E }, /* TIBETAN MARK TSA -PHRU -> '~' */ + { 0x3B, 0x5D }, /* TIBETAN MARK GUG RTAGS GYAS -> ']' */ + { 0x40, 0x6B }, /* TIBETAN LETTER KA -> 'k' */ + { 0x42, 0x67 }, /* TIBETAN LETTER GA -> 'g' */ + { 0x45, 0x63 }, /* TIBETAN LETTER CA -> 'c' */ + { 0x47, 0x6A }, /* TIBETAN LETTER JA -> 'j' */ + { 0x4F, 0x74 }, /* TIBETAN LETTER TA -> 't' */ + { 0x51, 0x64 }, /* TIBETAN LETTER DA -> 'd' */ + { 0x53, 0x6E }, /* TIBETAN LETTER NA -> 'n' */ + { 0x54, 0x70 }, /* TIBETAN LETTER PA -> 'p' */ + { 0x56, 0x62 }, /* TIBETAN LETTER BA -> 'b' */ + { 0x58, 0x6D }, /* TIBETAN LETTER MA -> 'm' */ + { 0x5D, 0x77 }, /* TIBETAN LETTER WA -> 'w' */ + { 0x5F, 0x7A }, /* TIBETAN LETTER ZA -> 'z' */ + { 0x60, 0x27 }, /* TIBETAN LETTER -A -> ''' */ + { 0x61, 0x79 }, /* TIBETAN LETTER YA -> 'y' */ + { 0x62, 0x72 }, /* TIBETAN LETTER RA -> 'r' */ + { 0x63, 0x6C }, /* TIBETAN LETTER LA -> 'l' */ + { 0x66, 0x73 }, /* TIBETAN LETTER SA -> 's' */ + { 0x67, 0x68 }, /* TIBETAN LETTER HA -> 'h' */ + { 0x68, 0x61 }, /* TIBETAN LETTER A -> 'a' */ + { 0x6A, 0x72 }, /* TIBETAN LETTER FIXED-FORM RA -> 'r' */ + { 0x72, 0x69 }, /* TIBETAN VOWEL SIGN I -> 'i' */ + { 0x74, 0x75 }, /* TIBETAN VOWEL SIGN U -> 'u' */ + { 0x76, 0x52 }, /* TIBETAN VOWEL SIGN VOCALIC R -> 'R' */ + { 0x78, 0x4C }, /* TIBETAN VOWEL SIGN VOCALIC L -> 'L' */ + { 0x7A, 0x65 }, /* TIBETAN VOWEL SIGN E -> 'e' */ + { 0x7C, 0x6F }, /* TIBETAN VOWEL SIGN O -> 'o' */ + { 0x7E, 0x4D }, /* TIBETAN SIGN RJES SU NGA RO -> 'M' */ + { 0x7F, 0x48 }, /* TIBETAN SIGN RNAM BCAD -> 'H' */ + { 0x80, 0x69 }, /* TIBETAN VOWEL SIGN REVERSED I -> 'i' */ + { 0x90, 0x6B }, /* TIBETAN SUBJOINED LETTER KA -> 'k' */ + { 0x92, 0x67 }, /* TIBETAN SUBJOINED LETTER GA -> 'g' */ + { 0x95, 0x63 }, /* TIBETAN SUBJOINED LETTER CA -> 'c' */ + { 0x97, 0x6A }, /* TIBETAN SUBJOINED LETTER JA -> 'j' */ + { 0x9F, 0x74 }, /* TIBETAN SUBJOINED LETTER TA -> 't' */ + { 0xA1, 0x64 }, /* TIBETAN SUBJOINED LETTER DA -> 'd' */ + { 0xA3, 0x6E }, /* TIBETAN SUBJOINED LETTER NA -> 'n' */ + { 0xA4, 0x70 }, /* TIBETAN SUBJOINED LETTER PA -> 'p' */ + { 0xA6, 0x62 }, /* TIBETAN SUBJOINED LETTER BA -> 'b' */ + { 0xA8, 0x6D }, /* TIBETAN SUBJOINED LETTER MA -> 'm' */ + { 0xAD, 0x77 }, /* TIBETAN SUBJOINED LETTER WA -> 'w' */ + { 0xAF, 0x7A }, /* TIBETAN SUBJOINED LETTER ZA -> 'z' */ + { 0xB0, 0x27 }, /* TIBETAN SUBJOINED LETTER -A -> ''' */ + { 0xB1, 0x79 }, /* TIBETAN SUBJOINED LETTER YA -> 'y' */ + { 0xB2, 0x72 }, /* TIBETAN SUBJOINED LETTER RA -> 'r' */ + { 0xB3, 0x6C }, /* TIBETAN SUBJOINED LETTER LA -> 'l' */ + { 0xB6, 0x73 }, /* TIBETAN SUBJOINED LETTER SA -> 's' */ + { 0xB7, 0x68 }, /* TIBETAN SUBJOINED LETTER HA -> 'h' */ + { 0xB8, 0x61 }, /* TIBETAN SUBJOINED LETTER A -> 'a' */ + { 0xBA, 0x77 }, /* TIBETAN SUBJOINED LETTER FIXED-FORM WA -> 'w' */ + { 0xBB, 0x79 }, /* TIBETAN SUBJOINED LETTER FIXED-FORM YA -> 'y' */ + { 0xBC, 0x72 }, /* TIBETAN SUBJOINED LETTER FIXED-FORM RA -> 'r' */ + { 0xBE, 0x58 }, /* TIBETAN KU RU KHA -> 'X' */ + /* Entries for page 0x10 */ + { 0x00, 0x6B }, /* MYANMAR LETTER KA -> 'k' */ + { 0x02, 0x67 }, /* MYANMAR LETTER GA -> 'g' */ + { 0x05, 0x63 }, /* MYANMAR LETTER CA -> 'c' */ + { 0x07, 0x6A }, /* MYANMAR LETTER JA -> 'j' */ + { 0x12, 0x64 }, /* MYANMAR LETTER DA -> 'd' */ + { 0x14, 0x6E }, /* MYANMAR LETTER NA -> 'n' */ + { 0x15, 0x70 }, /* MYANMAR LETTER PA -> 'p' */ + { 0x17, 0x62 }, /* MYANMAR LETTER BA -> 'b' */ + { 0x19, 0x6D }, /* MYANMAR LETTER MA -> 'm' */ + { 0x1A, 0x79 }, /* MYANMAR LETTER YA -> 'y' */ + { 0x1B, 0x72 }, /* MYANMAR LETTER RA -> 'r' */ + { 0x1C, 0x6C }, /* MYANMAR LETTER LA -> 'l' */ + { 0x1D, 0x77 }, /* MYANMAR LETTER WA -> 'w' */ + { 0x1E, 0x73 }, /* MYANMAR LETTER SA -> 's' */ + { 0x1F, 0x68 }, /* MYANMAR LETTER HA -> 'h' */ + { 0x21, 0x61 }, /* MYANMAR LETTER A -> 'a' */ + { 0x23, 0x69 }, /* MYANMAR LETTER I -> 'i' */ + { 0x25, 0x75 }, /* MYANMAR LETTER U -> 'u' */ + { 0x27, 0x65 }, /* MYANMAR LETTER E -> 'e' */ + { 0x29, 0x6F }, /* MYANMAR LETTER O -> 'o' */ + { 0x2D, 0x69 }, /* MYANMAR VOWEL SIGN I -> 'i' */ + { 0x2F, 0x75 }, /* MYANMAR VOWEL SIGN U -> 'u' */ + { 0x31, 0x65 }, /* MYANMAR VOWEL SIGN E -> 'e' */ + { 0x36, 0x4E }, /* MYANMAR SIGN ANUSVARA -> 'N' */ + { 0x37, 0x27 }, /* MYANMAR SIGN DOT BELOW -> ''' */ + { 0x38, 0x3A }, /* MYANMAR SIGN VISARGA -> ':' */ + { 0x40, 0x30 }, /* MYANMAR DIGIT ZERO -> '0' */ + { 0x41, 0x31 }, /* MYANMAR DIGIT ONE -> '1' */ + { 0x42, 0x32 }, /* MYANMAR DIGIT TWO -> '2' */ + { 0x43, 0x33 }, /* MYANMAR DIGIT THREE -> '3' */ + { 0x44, 0x34 }, /* MYANMAR DIGIT FOUR -> '4' */ + { 0x45, 0x35 }, /* MYANMAR DIGIT FIVE -> '5' */ + { 0x46, 0x36 }, /* MYANMAR DIGIT SIX -> '6' */ + { 0x47, 0x37 }, /* MYANMAR DIGIT SEVEN -> '7' */ + { 0x48, 0x38 }, /* MYANMAR DIGIT EIGHT -> '8' */ + { 0x49, 0x39 }, /* MYANMAR DIGIT NINE -> '9' */ + { 0x52, 0x52 }, /* MYANMAR LETTER VOCALIC R -> 'R' */ + { 0x54, 0x4C }, /* MYANMAR LETTER VOCALIC L -> 'L' */ + { 0x56, 0x52 }, /* MYANMAR VOWEL SIGN VOCALIC R -> 'R' */ + { 0x58, 0x4C }, /* MYANMAR VOWEL SIGN VOCALIC L -> 'L' */ + { 0xA0, 0x41 }, /* GEORGIAN CAPITAL LETTER AN -> 'A' */ + { 0xA1, 0x42 }, /* GEORGIAN CAPITAL LETTER BAN -> 'B' */ + { 0xA2, 0x47 }, /* GEORGIAN CAPITAL LETTER GAN -> 'G' */ + { 0xA3, 0x44 }, /* GEORGIAN CAPITAL LETTER DON -> 'D' */ + { 0xA4, 0x45 }, /* GEORGIAN CAPITAL LETTER EN -> 'E' */ + { 0xA5, 0x56 }, /* GEORGIAN CAPITAL LETTER VIN -> 'V' */ + { 0xA6, 0x5A }, /* GEORGIAN CAPITAL LETTER ZEN -> 'Z' */ + { 0xA8, 0x49 }, /* GEORGIAN CAPITAL LETTER IN -> 'I' */ + { 0xA9, 0x4B }, /* GEORGIAN CAPITAL LETTER KAN -> 'K' */ + { 0xAA, 0x4C }, /* GEORGIAN CAPITAL LETTER LAS -> 'L' */ + { 0xAB, 0x4D }, /* GEORGIAN CAPITAL LETTER MAN -> 'M' */ + { 0xAC, 0x4E }, /* GEORGIAN CAPITAL LETTER NAR -> 'N' */ + { 0xAD, 0x4F }, /* GEORGIAN CAPITAL LETTER ON -> 'O' */ + { 0xAE, 0x50 }, /* GEORGIAN CAPITAL LETTER PAR -> 'P' */ + { 0xB0, 0x52 }, /* GEORGIAN CAPITAL LETTER RAE -> 'R' */ + { 0xB1, 0x53 }, /* GEORGIAN CAPITAL LETTER SAN -> 'S' */ + { 0xB2, 0x54 }, /* GEORGIAN CAPITAL LETTER TAR -> 'T' */ + { 0xB3, 0x55 }, /* GEORGIAN CAPITAL LETTER UN -> 'U' */ + { 0xB7, 0x51 }, /* GEORGIAN CAPITAL LETTER QAR -> 'Q' */ + { 0xBC, 0x43 }, /* GEORGIAN CAPITAL LETTER CIL -> 'C' */ + { 0xBE, 0x58 }, /* GEORGIAN CAPITAL LETTER XAN -> 'X' */ + { 0xBF, 0x4A }, /* GEORGIAN CAPITAL LETTER JHAN -> 'J' */ + { 0xC0, 0x48 }, /* GEORGIAN CAPITAL LETTER HAE -> 'H' */ + { 0xC1, 0x45 }, /* GEORGIAN CAPITAL LETTER HE -> 'E' */ + { 0xC2, 0x59 }, /* GEORGIAN CAPITAL LETTER HIE -> 'Y' */ + { 0xC3, 0x57 }, /* GEORGIAN CAPITAL LETTER WE -> 'W' */ + { 0xD0, 0x61 }, /* GEORGIAN LETTER AN -> 'a' */ + { 0xD1, 0x62 }, /* GEORGIAN LETTER BAN -> 'b' */ + { 0xD2, 0x67 }, /* GEORGIAN LETTER GAN -> 'g' */ + { 0xD3, 0x64 }, /* GEORGIAN LETTER DON -> 'd' */ + { 0xD4, 0x65 }, /* GEORGIAN LETTER EN -> 'e' */ + { 0xD5, 0x76 }, /* GEORGIAN LETTER VIN -> 'v' */ + { 0xD6, 0x7A }, /* GEORGIAN LETTER ZEN -> 'z' */ + { 0xD8, 0x69 }, /* GEORGIAN LETTER IN -> 'i' */ + { 0xD9, 0x6B }, /* GEORGIAN LETTER KAN -> 'k' */ + { 0xDA, 0x6C }, /* GEORGIAN LETTER LAS -> 'l' */ + { 0xDB, 0x6D }, /* GEORGIAN LETTER MAN -> 'm' */ + { 0xDC, 0x6E }, /* GEORGIAN LETTER NAR -> 'n' */ + { 0xDD, 0x6F }, /* GEORGIAN LETTER ON -> 'o' */ + { 0xDE, 0x70 }, /* GEORGIAN LETTER PAR -> 'p' */ + { 0xE0, 0x72 }, /* GEORGIAN LETTER RAE -> 'r' */ + { 0xE1, 0x73 }, /* GEORGIAN LETTER SAN -> 's' */ + { 0xE2, 0x74 }, /* GEORGIAN LETTER TAR -> 't' */ + { 0xE3, 0x75 }, /* GEORGIAN LETTER UN -> 'u' */ + { 0xE7, 0x71 }, /* GEORGIAN LETTER QAR -> 'q' */ + { 0xEC, 0x63 }, /* GEORGIAN LETTER CIL -> 'c' */ + { 0xEE, 0x78 }, /* GEORGIAN LETTER XAN -> 'x' */ + { 0xEF, 0x6A }, /* GEORGIAN LETTER JHAN -> 'j' */ + { 0xF0, 0x68 }, /* GEORGIAN LETTER HAE -> 'h' */ + { 0xF1, 0x65 }, /* GEORGIAN LETTER HE -> 'e' */ + { 0xF2, 0x79 }, /* GEORGIAN LETTER HIE -> 'y' */ + { 0xF3, 0x77 }, /* GEORGIAN LETTER WE -> 'w' */ + { 0xF6, 0x66 }, /* GEORGIAN LETTER FI -> 'f' */ + /* Entries for page 0x11 */ + { 0x00, 0x67 }, /* HANGUL CHOSEONG KIYEOK -> 'g' */ + { 0x02, 0x6E }, /* HANGUL CHOSEONG NIEUN -> 'n' */ + { 0x03, 0x64 }, /* HANGUL CHOSEONG TIKEUT -> 'd' */ + { 0x05, 0x72 }, /* HANGUL CHOSEONG RIEUL -> 'r' */ + { 0x06, 0x6D }, /* HANGUL CHOSEONG MIEUM -> 'm' */ + { 0x07, 0x62 }, /* HANGUL CHOSEONG PIEUP -> 'b' */ + { 0x09, 0x73 }, /* HANGUL CHOSEONG SIOS -> 's' */ + { 0x0C, 0x6A }, /* HANGUL CHOSEONG CIEUC -> 'j' */ + { 0x0E, 0x63 }, /* HANGUL CHOSEONG CHIEUCH -> 'c' */ + { 0x0F, 0x6B }, /* HANGUL CHOSEONG KHIEUKH -> 'k' */ + { 0x10, 0x74 }, /* HANGUL CHOSEONG THIEUTH -> 't' */ + { 0x11, 0x70 }, /* HANGUL CHOSEONG PHIEUPH -> 'p' */ + { 0x12, 0x68 }, /* HANGUL CHOSEONG HIEUH -> 'h' */ + { 0x35, 0x73 }, /* HANGUL CHOSEONG SIOS-IEUNG -> 's' */ + { 0x40, 0x5A }, /* HANGUL CHOSEONG PANSIOS -> 'Z' */ + { 0x41, 0x67 }, /* HANGUL CHOSEONG IEUNG-KIYEOK -> 'g' */ + { 0x42, 0x64 }, /* HANGUL CHOSEONG IEUNG-TIKEUT -> 'd' */ + { 0x43, 0x6D }, /* HANGUL CHOSEONG IEUNG-MIEUM -> 'm' */ + { 0x44, 0x62 }, /* HANGUL CHOSEONG IEUNG-PIEUP -> 'b' */ + { 0x45, 0x73 }, /* HANGUL CHOSEONG IEUNG-SIOS -> 's' */ + { 0x46, 0x5A }, /* HANGUL CHOSEONG IEUNG-PANSIOS -> 'Z' */ + { 0x48, 0x6A }, /* HANGUL CHOSEONG IEUNG-CIEUC -> 'j' */ + { 0x49, 0x63 }, /* HANGUL CHOSEONG IEUNG-CHIEUCH -> 'c' */ + { 0x4A, 0x74 }, /* HANGUL CHOSEONG IEUNG-THIEUTH -> 't' */ + { 0x4B, 0x70 }, /* HANGUL CHOSEONG IEUNG-PHIEUPH -> 'p' */ + { 0x4C, 0x4E }, /* HANGUL CHOSEONG YESIEUNG -> 'N' */ + { 0x4D, 0x6A }, /* HANGUL CHOSEONG CIEUC-IEUNG -> 'j' */ + { 0x59, 0x51 }, /* HANGUL CHOSEONG YEORINHIEUH -> 'Q' */ + { 0x61, 0x61 }, /* HANGUL JUNGSEONG A -> 'a' */ + { 0x66, 0x65 }, /* HANGUL JUNGSEONG E -> 'e' */ + { 0x69, 0x6F }, /* HANGUL JUNGSEONG O -> 'o' */ + { 0x6E, 0x75 }, /* HANGUL JUNGSEONG U -> 'u' */ + { 0x75, 0x69 }, /* HANGUL JUNGSEONG I -> 'i' */ + { 0x9E, 0x55 }, /* HANGUL JUNGSEONG ARAEA -> 'U' */ + { 0xA8, 0x67 }, /* HANGUL JONGSEONG KIYEOK -> 'g' */ + { 0xAB, 0x6E }, /* HANGUL JONGSEONG NIEUN -> 'n' */ + { 0xAE, 0x64 }, /* HANGUL JONGSEONG TIKEUT -> 'd' */ + { 0xAF, 0x6C }, /* HANGUL JONGSEONG RIEUL -> 'l' */ + { 0xB7, 0x6D }, /* HANGUL JONGSEONG MIEUM -> 'm' */ + { 0xB8, 0x62 }, /* HANGUL JONGSEONG PIEUP -> 'b' */ + { 0xBA, 0x73 }, /* HANGUL JONGSEONG SIOS -> 's' */ + { 0xBD, 0x6A }, /* HANGUL JONGSEONG CIEUC -> 'j' */ + { 0xBE, 0x63 }, /* HANGUL JONGSEONG CHIEUCH -> 'c' */ + { 0xBF, 0x6B }, /* HANGUL JONGSEONG KHIEUKH -> 'k' */ + { 0xC0, 0x74 }, /* HANGUL JONGSEONG THIEUTH -> 't' */ + { 0xC1, 0x70 }, /* HANGUL JONGSEONG PHIEUPH -> 'p' */ + { 0xC2, 0x68 }, /* HANGUL JONGSEONG HIEUH -> 'h' */ + { 0xEB, 0x5A }, /* HANGUL JONGSEONG PANSIOS -> 'Z' */ + { 0xEC, 0x67 }, /* HANGUL JONGSEONG IEUNG-KIYEOK -> 'g' */ + { 0xF0, 0x4E }, /* HANGUL JONGSEONG YESIEUNG -> 'N' */ + { 0xF9, 0x51 }, /* HANGUL JONGSEONG YEORINHIEUH -> 'Q' */ + /* Entries for page 0x13 */ + { 0x61, 0x20 }, /* ETHIOPIC WORDSPACE -> ' ' */ + { 0x62, 0x2E }, /* ETHIOPIC FULL STOP -> '.' */ + { 0x63, 0x2C }, /* ETHIOPIC COMMA -> ',' */ + { 0x64, 0x3B }, /* ETHIOPIC SEMICOLON -> ';' */ + { 0x65, 0x3A }, /* ETHIOPIC COLON -> ':' */ + { 0x67, 0x3F }, /* ETHIOPIC QUESTION MARK -> '?' */ + { 0x69, 0x31 }, /* ETHIOPIC DIGIT ONE -> '1' */ + { 0x6A, 0x32 }, /* ETHIOPIC DIGIT TWO -> '2' */ + { 0x6B, 0x33 }, /* ETHIOPIC DIGIT THREE -> '3' */ + { 0x6C, 0x34 }, /* ETHIOPIC DIGIT FOUR -> '4' */ + { 0x6D, 0x35 }, /* ETHIOPIC DIGIT FIVE -> '5' */ + { 0x6E, 0x36 }, /* ETHIOPIC DIGIT SIX -> '6' */ + { 0x6F, 0x37 }, /* ETHIOPIC DIGIT SEVEN -> '7' */ + { 0x70, 0x38 }, /* ETHIOPIC DIGIT EIGHT -> '8' */ + { 0x71, 0x39 }, /* ETHIOPIC DIGIT NINE -> '9' */ + { 0xA0, 0x61 }, /* CHEROKEE LETTER A -> 'a' */ + { 0xA1, 0x65 }, /* CHEROKEE LETTER E -> 'e' */ + { 0xA2, 0x69 }, /* CHEROKEE LETTER I -> 'i' */ + { 0xA3, 0x6F }, /* CHEROKEE LETTER O -> 'o' */ + { 0xA4, 0x75 }, /* CHEROKEE LETTER U -> 'u' */ + { 0xA5, 0x76 }, /* CHEROKEE LETTER V -> 'v' */ + { 0xCD, 0x73 }, /* CHEROKEE LETTER S -> 's' */ + /* Entries for page 0x14 */ + { 0x01, 0x65 }, /* CANADIAN SYLLABICS E -> 'e' */ + { 0x03, 0x69 }, /* CANADIAN SYLLABICS I -> 'i' */ + { 0x05, 0x6F }, /* CANADIAN SYLLABICS O -> 'o' */ + { 0x09, 0x69 }, /* CANADIAN SYLLABICS CARRIER I -> 'i' */ + { 0x0A, 0x61 }, /* CANADIAN SYLLABICS A -> 'a' */ + { 0x1D, 0x77 }, /* CANADIAN SYLLABICS Y-CREE W -> 'w' */ + { 0x1E, 0x27 }, /* CANADIAN SYLLABICS GLOTTAL STOP -> ''' */ + { 0x1F, 0x74 }, /* CANADIAN SYLLABICS FINAL ACUTE -> 't' */ + { 0x20, 0x6B }, /* CANADIAN SYLLABICS FINAL GRAVE -> 'k' */ + { 0x22, 0x73 }, /* CANADIAN SYLLABICS FINAL TOP HALF RING -> 's' */ + { 0x23, 0x6E }, /* CANADIAN SYLLABICS FINAL RIGHT HALF RING -> 'n' */ + { 0x24, 0x77 }, /* CANADIAN SYLLABICS FINAL RING -> 'w' */ + { 0x25, 0x6E }, /* CANADIAN SYLLABICS FINAL DOUBLE ACUTE -> 'n' */ + { 0x27, 0x77 }, /* CANADIAN SYLLABICS FINAL MIDDLE DOT -> 'w' */ + { 0x28, 0x63 }, /* CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE -> 'c' */ + { 0x29, 0x3F }, /* CANADIAN SYLLABICS FINAL PLUS -> '?' */ + { 0x2A, 0x6C }, /* CANADIAN SYLLABICS FINAL DOWN TACK -> 'l' */ + { 0x49, 0x70 }, /* CANADIAN SYLLABICS P -> 'p' */ + { 0x4A, 0x70 }, /* CANADIAN SYLLABICS WEST-CREE P -> 'p' */ + { 0x4B, 0x68 }, /* CANADIAN SYLLABICS CARRIER H -> 'h' */ + { 0x66, 0x74 }, /* CANADIAN SYLLABICS T -> 't' */ + { 0x83, 0x6B }, /* CANADIAN SYLLABICS K -> 'k' */ + { 0xA1, 0x63 }, /* CANADIAN SYLLABICS C -> 'c' */ + { 0xBB, 0x6D }, /* CANADIAN SYLLABICS M -> 'm' */ + { 0xBC, 0x6D }, /* CANADIAN SYLLABICS WEST-CREE M -> 'm' */ + { 0xBE, 0x6D }, /* CANADIAN SYLLABICS ATHAPASCAN M -> 'm' */ + { 0xBF, 0x6D }, /* CANADIAN SYLLABICS SAYISI M -> 'm' */ + { 0xD0, 0x6E }, /* CANADIAN SYLLABICS N -> 'n' */ + { 0xEA, 0x00 }, /* CANADIAN SYLLABICS L -> ... */ + { 0xEC, 0x6C }, /* CANADIAN SYLLABICS MEDIAL L -> 'l' */ + /* Entries for page 0x15 */ + { 0x05, 0x73 }, /* CANADIAN SYLLABICS S -> 's' */ + { 0x06, 0x73 }, /* CANADIAN SYLLABICS ATHAPASCAN S -> 's' */ + { 0x08, 0x73 }, /* CANADIAN SYLLABICS BLACKFOOT S -> 's' */ + { 0x3E, 0x00 }, /* CANADIAN SYLLABICS Y -> ... */ + { 0x40, 0x79 }, /* CANADIAN SYLLABICS WEST-CREE Y -> 'y' */ + { 0x50, 0x00 }, /* CANADIAN SYLLABICS R -> ... */ + { 0x52, 0x72 }, /* CANADIAN SYLLABICS MEDIAL R -> 'r' */ + { 0x5D, 0x66 }, /* CANADIAN SYLLABICS F -> 'f' */ + { 0x7B, 0x68 }, /* CANADIAN SYLLABICS NUNAVIK H -> 'h' */ + { 0x7C, 0x68 }, /* CANADIAN SYLLABICS NUNAVUT H -> 'h' */ + { 0x85, 0x71 }, /* CANADIAN SYLLABICS Q -> 'q' */ + { 0xAF, 0x62 }, /* CANADIAN SYLLABICS AIVILIK B -> 'b' */ + { 0xB0, 0x65 }, /* CANADIAN SYLLABICS BLACKFOOT E -> 'e' */ + { 0xB1, 0x69 }, /* CANADIAN SYLLABICS BLACKFOOT I -> 'i' */ + { 0xB2, 0x6F }, /* CANADIAN SYLLABICS BLACKFOOT O -> 'o' */ + { 0xB3, 0x61 }, /* CANADIAN SYLLABICS BLACKFOOT A -> 'a' */ + { 0xEE, 0x70 }, /* CANADIAN SYLLABICS CARRIER P -> 'p' */ + /* Entries for page 0x16 */ + { 0x46, 0x7A }, /* CANADIAN SYLLABICS CARRIER Z -> 'z' */ + { 0x47, 0x7A }, /* CANADIAN SYLLABICS CARRIER INITIAL Z -> 'z' */ + { 0x6D, 0x58 }, /* CANADIAN SYLLABICS CHI SIGN -> 'X' */ + { 0x6E, 0x2E }, /* CANADIAN SYLLABICS FULL STOP -> '.' */ + { 0x80, 0x20 }, /* OGHAM SPACE MARK -> ' ' */ + { 0x81, 0x62 }, /* OGHAM LETTER BEITH -> 'b' */ + { 0x82, 0x6C }, /* OGHAM LETTER LUIS -> 'l' */ + { 0x83, 0x66 }, /* OGHAM LETTER FEARN -> 'f' */ + { 0x84, 0x73 }, /* OGHAM LETTER SAIL -> 's' */ + { 0x85, 0x6E }, /* OGHAM LETTER NION -> 'n' */ + { 0x86, 0x68 }, /* OGHAM LETTER UATH -> 'h' */ + { 0x87, 0x64 }, /* OGHAM LETTER DAIR -> 'd' */ + { 0x88, 0x74 }, /* OGHAM LETTER TINNE -> 't' */ + { 0x89, 0x63 }, /* OGHAM LETTER COLL -> 'c' */ + { 0x8A, 0x71 }, /* OGHAM LETTER CEIRT -> 'q' */ + { 0x8B, 0x6D }, /* OGHAM LETTER MUIN -> 'm' */ + { 0x8C, 0x67 }, /* OGHAM LETTER GORT -> 'g' */ + { 0x8E, 0x7A }, /* OGHAM LETTER STRAIF -> 'z' */ + { 0x8F, 0x72 }, /* OGHAM LETTER RUIS -> 'r' */ + { 0x90, 0x61 }, /* OGHAM LETTER AILM -> 'a' */ + { 0x91, 0x6F }, /* OGHAM LETTER ONN -> 'o' */ + { 0x92, 0x75 }, /* OGHAM LETTER UR -> 'u' */ + { 0x93, 0x65 }, /* OGHAM LETTER EADHADH -> 'e' */ + { 0x94, 0x69 }, /* OGHAM LETTER IODHADH -> 'i' */ + { 0x98, 0x70 }, /* OGHAM LETTER IFIN -> 'p' */ + { 0x99, 0x78 }, /* OGHAM LETTER EAMHANCHOLL -> 'x' */ + { 0x9A, 0x70 }, /* OGHAM LETTER PEITH -> 'p' */ + { 0x9B, 0x3C }, /* OGHAM FEATHER MARK -> '<' */ + { 0x9C, 0x3E }, /* OGHAM REVERSED FEATHER MARK -> '>' */ + { 0xA0, 0x66 }, /* RUNIC LETTER FEHU FEOH FE F -> 'f' */ + { 0xA1, 0x76 }, /* RUNIC LETTER V -> 'v' */ + { 0xA2, 0x75 }, /* RUNIC LETTER URUZ UR U -> 'u' */ + { 0xA4, 0x79 }, /* RUNIC LETTER Y -> 'y' */ + { 0xA5, 0x77 }, /* RUNIC LETTER W -> 'w' */ + { 0xA8, 0x61 }, /* RUNIC LETTER ANSUZ A -> 'a' */ + { 0xA9, 0x6F }, /* RUNIC LETTER OS O -> 'o' */ + { 0xAC, 0x00 }, /* RUNIC LETTER LONG-BRANCH-OSS O -> ... */ + { 0xAE, 0x6F }, /* RUNIC LETTER O -> 'o' */ + { 0xB1, 0x72 }, /* RUNIC LETTER RAIDO RAD REID R -> 'r' */ + { 0xB2, 0x6B }, /* RUNIC LETTER KAUNA -> 'k' */ + { 0xB3, 0x63 }, /* RUNIC LETTER CEN -> 'c' */ + { 0xB4, 0x6B }, /* RUNIC LETTER KAUN K -> 'k' */ + { 0xB5, 0x67 }, /* RUNIC LETTER G -> 'g' */ + { 0xB7, 0x67 }, /* RUNIC LETTER GEBO GYFU G -> 'g' */ + { 0xB8, 0x67 }, /* RUNIC LETTER GAR -> 'g' */ + { 0xB9, 0x77 }, /* RUNIC LETTER WUNJO WYNN W -> 'w' */ + { 0xBA, 0x00 }, /* RUNIC LETTER HAGLAZ H -> ... */ + { 0xBD, 0x68 }, /* RUNIC LETTER SHORT-TWIG-HAGALL H -> 'h' */ + { 0xBE, 0x00 }, /* RUNIC LETTER NAUDIZ NYD NAUD N -> ... */ + { 0xC0, 0x6E }, /* RUNIC LETTER DOTTED-N -> 'n' */ + { 0xC1, 0x69 }, /* RUNIC LETTER ISAZ IS ISS I -> 'i' */ + { 0xC2, 0x65 }, /* RUNIC LETTER E -> 'e' */ + { 0xC3, 0x6A }, /* RUNIC LETTER JERAN J -> 'j' */ + { 0xC4, 0x67 }, /* RUNIC LETTER GER -> 'g' */ + { 0xC6, 0x61 }, /* RUNIC LETTER SHORT-TWIG-AR A -> 'a' */ + { 0xC8, 0x70 }, /* RUNIC LETTER PERTHO PEORTH P -> 'p' */ + { 0xC9, 0x7A }, /* RUNIC LETTER ALGIZ EOLHX -> 'z' */ + { 0xCA, 0x00 }, /* RUNIC LETTER SOWILO S -> ... */ + { 0xCC, 0x73 }, /* RUNIC LETTER SHORT-TWIG-SOL S -> 's' */ + { 0xCD, 0x63 }, /* RUNIC LETTER C -> 'c' */ + { 0xCE, 0x7A }, /* RUNIC LETTER Z -> 'z' */ + { 0xCF, 0x74 }, /* RUNIC LETTER TIWAZ TIR TYR T -> 't' */ + { 0xD0, 0x74 }, /* RUNIC LETTER SHORT-TWIG-TYR T -> 't' */ + { 0xD1, 0x64 }, /* RUNIC LETTER D -> 'd' */ + { 0xD2, 0x62 }, /* RUNIC LETTER BERKANAN BEORC BJARKAN B -> 'b' */ + { 0xD3, 0x62 }, /* RUNIC LETTER SHORT-TWIG-BJARKAN B -> 'b' */ + { 0xD4, 0x70 }, /* RUNIC LETTER DOTTED-P -> 'p' */ + { 0xD5, 0x70 }, /* RUNIC LETTER OPEN-P -> 'p' */ + { 0xD6, 0x65 }, /* RUNIC LETTER EHWAZ EH E -> 'e' */ + { 0xD7, 0x00 }, /* RUNIC LETTER MANNAZ MAN M -> ... */ + { 0xD9, 0x6D }, /* RUNIC LETTER SHORT-TWIG-MADR M -> 'm' */ + { 0xDA, 0x6C }, /* RUNIC LETTER LAUKAZ LAGU LOGR L -> 'l' */ + { 0xDB, 0x6C }, /* RUNIC LETTER DOTTED-L -> 'l' */ + { 0xDE, 0x64 }, /* RUNIC LETTER DAGAZ DAEG D -> 'd' */ + { 0xDF, 0x6F }, /* RUNIC LETTER OTHALAN ETHEL O -> 'o' */ + { 0xE5, 0x73 }, /* RUNIC LETTER STAN -> 's' */ + { 0xE9, 0x71 }, /* RUNIC LETTER Q -> 'q' */ + { 0xEA, 0x78 }, /* RUNIC LETTER X -> 'x' */ + { 0xEB, 0x2E }, /* RUNIC SINGLE PUNCTUATION -> '.' */ + { 0xEC, 0x3A }, /* RUNIC MULTIPLE PUNCTUATION -> ':' */ + { 0xED, 0x2B }, /* RUNIC CROSS PUNCTUATION -> '+' */ + /* Entries for page 0x17 */ + { 0x80, 0x6B }, /* KHMER LETTER KA -> 'k' */ + { 0x82, 0x67 }, /* KHMER LETTER KO -> 'g' */ + { 0x85, 0x63 }, /* KHMER LETTER CA -> 'c' */ + { 0x87, 0x6A }, /* KHMER LETTER CO -> 'j' */ + { 0x8A, 0x74 }, /* KHMER LETTER DA -> 't' */ + { 0x8C, 0x64 }, /* KHMER LETTER DO -> 'd' */ + { 0x8F, 0x74 }, /* KHMER LETTER TA -> 't' */ + { 0x91, 0x64 }, /* KHMER LETTER TO -> 'd' */ + { 0x93, 0x6E }, /* KHMER LETTER NO -> 'n' */ + { 0x94, 0x70 }, /* KHMER LETTER BA -> 'p' */ + { 0x96, 0x62 }, /* KHMER LETTER PO -> 'b' */ + { 0x98, 0x6D }, /* KHMER LETTER MO -> 'm' */ + { 0x99, 0x79 }, /* KHMER LETTER YO -> 'y' */ + { 0x9A, 0x72 }, /* KHMER LETTER RO -> 'r' */ + { 0x9B, 0x6C }, /* KHMER LETTER LO -> 'l' */ + { 0x9C, 0x76 }, /* KHMER LETTER VO -> 'v' */ + { 0x9F, 0x73 }, /* KHMER LETTER SA -> 's' */ + { 0xA0, 0x68 }, /* KHMER LETTER HA -> 'h' */ + { 0xA1, 0x6C }, /* KHMER LETTER LA -> 'l' */ + { 0xA2, 0x71 }, /* KHMER LETTER QA -> 'q' */ + { 0xA3, 0x61 }, /* KHMER INDEPENDENT VOWEL QAQ -> 'a' */ + { 0xA5, 0x69 }, /* KHMER INDEPENDENT VOWEL QI -> 'i' */ + { 0xA7, 0x75 }, /* KHMER INDEPENDENT VOWEL QU -> 'u' */ + { 0xAF, 0x65 }, /* KHMER INDEPENDENT VOWEL QE -> 'e' */ + { 0xB4, 0x61 }, /* KHMER VOWEL INHERENT AQ -> 'a' */ + { 0xB7, 0x69 }, /* KHMER VOWEL SIGN I -> 'i' */ + { 0xB9, 0x79 }, /* KHMER VOWEL SIGN Y -> 'y' */ + { 0xBB, 0x75 }, /* KHMER VOWEL SIGN U -> 'u' */ + { 0xC1, 0x65 }, /* KHMER VOWEL SIGN E -> 'e' */ + { 0xC6, 0x4D }, /* KHMER SIGN NIKAHIT -> 'M' */ + { 0xC7, 0x48 }, /* KHMER SIGN REAHMUK -> 'H' */ + { 0xCC, 0x72 }, /* KHMER SIGN ROBAT -> 'r' */ + { 0xCE, 0x21 }, /* KHMER SIGN KAKABAT -> '!' */ + { 0xD4, 0x2E }, /* KHMER SIGN KHAN -> '.' */ + { 0xD6, 0x3A }, /* KHMER SIGN CAMNUC PII KUUH -> ':' */ + { 0xD7, 0x2B }, /* KHMER SIGN LEK TOO -> '+' */ + { 0xDC, 0x27 }, /* KHMER SIGN AVAKRAHASANYA -> ''' */ + { 0xE0, 0x30 }, /* KHMER DIGIT ZERO -> '0' */ + { 0xE1, 0x31 }, /* KHMER DIGIT ONE -> '1' */ + { 0xE2, 0x32 }, /* KHMER DIGIT TWO -> '2' */ + { 0xE3, 0x33 }, /* KHMER DIGIT THREE -> '3' */ + { 0xE4, 0x34 }, /* KHMER DIGIT FOUR -> '4' */ + { 0xE5, 0x35 }, /* KHMER DIGIT FIVE -> '5' */ + { 0xE6, 0x36 }, /* KHMER DIGIT SIX -> '6' */ + { 0xE7, 0x37 }, /* KHMER DIGIT SEVEN -> '7' */ + { 0xE8, 0x38 }, /* KHMER DIGIT EIGHT -> '8' */ + { 0xE9, 0x39 }, /* KHMER DIGIT NINE -> '9' */ + /* Entries for page 0x18 */ + { 0x07, 0x2D }, /* MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER -> '-' */ + { 0x10, 0x30 }, /* MONGOLIAN DIGIT ZERO -> '0' */ + { 0x11, 0x31 }, /* MONGOLIAN DIGIT ONE -> '1' */ + { 0x12, 0x32 }, /* MONGOLIAN DIGIT TWO -> '2' */ + { 0x13, 0x33 }, /* MONGOLIAN DIGIT THREE -> '3' */ + { 0x14, 0x34 }, /* MONGOLIAN DIGIT FOUR -> '4' */ + { 0x15, 0x35 }, /* MONGOLIAN DIGIT FIVE -> '5' */ + { 0x16, 0x36 }, /* MONGOLIAN DIGIT SIX -> '6' */ + { 0x17, 0x37 }, /* MONGOLIAN DIGIT SEVEN -> '7' */ + { 0x18, 0x38 }, /* MONGOLIAN DIGIT EIGHT -> '8' */ + { 0x19, 0x39 }, /* MONGOLIAN DIGIT NINE -> '9' */ + { 0x20, 0x61 }, /* MONGOLIAN LETTER A -> 'a' */ + { 0x21, 0x65 }, /* MONGOLIAN LETTER E -> 'e' */ + { 0x22, 0x69 }, /* MONGOLIAN LETTER I -> 'i' */ + { 0x23, 0x6F }, /* MONGOLIAN LETTER O -> 'o' */ + { 0x24, 0x75 }, /* MONGOLIAN LETTER U -> 'u' */ + { 0x25, 0x4F }, /* MONGOLIAN LETTER OE -> 'O' */ + { 0x26, 0x55 }, /* MONGOLIAN LETTER UE -> 'U' */ + { 0x28, 0x6E }, /* MONGOLIAN LETTER NA -> 'n' */ + { 0x2A, 0x62 }, /* MONGOLIAN LETTER BA -> 'b' */ + { 0x2B, 0x70 }, /* MONGOLIAN LETTER PA -> 'p' */ + { 0x2C, 0x71 }, /* MONGOLIAN LETTER QA -> 'q' */ + { 0x2D, 0x67 }, /* MONGOLIAN LETTER GA -> 'g' */ + { 0x2E, 0x6D }, /* MONGOLIAN LETTER MA -> 'm' */ + { 0x2F, 0x6C }, /* MONGOLIAN LETTER LA -> 'l' */ + { 0x30, 0x73 }, /* MONGOLIAN LETTER SA -> 's' */ + { 0x32, 0x74 }, /* MONGOLIAN LETTER TA -> 't' */ + { 0x33, 0x64 }, /* MONGOLIAN LETTER DA -> 'd' */ + { 0x35, 0x6A }, /* MONGOLIAN LETTER JA -> 'j' */ + { 0x36, 0x79 }, /* MONGOLIAN LETTER YA -> 'y' */ + { 0x37, 0x72 }, /* MONGOLIAN LETTER RA -> 'r' */ + { 0x38, 0x77 }, /* MONGOLIAN LETTER WA -> 'w' */ + { 0x39, 0x66 }, /* MONGOLIAN LETTER FA -> 'f' */ + { 0x3A, 0x6B }, /* MONGOLIAN LETTER KA -> 'k' */ + { 0x3D, 0x7A }, /* MONGOLIAN LETTER ZA -> 'z' */ + { 0x3E, 0x68 }, /* MONGOLIAN LETTER HAA -> 'h' */ + { 0x43, 0x2D }, /* MONGOLIAN LETTER TODO LONG VOWEL SIGN -> '-' */ + { 0x44, 0x65 }, /* MONGOLIAN LETTER TODO E -> 'e' */ + { 0x45, 0x69 }, /* MONGOLIAN LETTER TODO I -> 'i' */ + { 0x46, 0x6F }, /* MONGOLIAN LETTER TODO O -> 'o' */ + { 0x47, 0x75 }, /* MONGOLIAN LETTER TODO U -> 'u' */ + { 0x48, 0x4F }, /* MONGOLIAN LETTER TODO OE -> 'O' */ + { 0x49, 0x55 }, /* MONGOLIAN LETTER TODO UE -> 'U' */ + { 0x4B, 0x62 }, /* MONGOLIAN LETTER TODO BA -> 'b' */ + { 0x4C, 0x70 }, /* MONGOLIAN LETTER TODO PA -> 'p' */ + { 0x4D, 0x71 }, /* MONGOLIAN LETTER TODO QA -> 'q' */ + { 0x4E, 0x67 }, /* MONGOLIAN LETTER TODO GA -> 'g' */ + { 0x4F, 0x6D }, /* MONGOLIAN LETTER TODO MA -> 'm' */ + { 0x50, 0x74 }, /* MONGOLIAN LETTER TODO TA -> 't' */ + { 0x51, 0x64 }, /* MONGOLIAN LETTER TODO DA -> 'd' */ + { 0x53, 0x6A }, /* MONGOLIAN LETTER TODO JA -> 'j' */ + { 0x55, 0x79 }, /* MONGOLIAN LETTER TODO YA -> 'y' */ + { 0x56, 0x77 }, /* MONGOLIAN LETTER TODO WA -> 'w' */ + { 0x57, 0x6B }, /* MONGOLIAN LETTER TODO KA -> 'k' */ + { 0x58, 0x67 }, /* MONGOLIAN LETTER TODO GAA -> 'g' */ + { 0x59, 0x68 }, /* MONGOLIAN LETTER TODO HAA -> 'h' */ + { 0x5D, 0x65 }, /* MONGOLIAN LETTER SIBE E -> 'e' */ + { 0x5E, 0x69 }, /* MONGOLIAN LETTER SIBE I -> 'i' */ + { 0x60, 0x55 }, /* MONGOLIAN LETTER SIBE UE -> 'U' */ + { 0x61, 0x75 }, /* MONGOLIAN LETTER SIBE U -> 'u' */ + { 0x63, 0x6B }, /* MONGOLIAN LETTER SIBE KA -> 'k' */ + { 0x64, 0x67 }, /* MONGOLIAN LETTER SIBE GA -> 'g' */ + { 0x65, 0x68 }, /* MONGOLIAN LETTER SIBE HA -> 'h' */ + { 0x66, 0x70 }, /* MONGOLIAN LETTER SIBE PA -> 'p' */ + { 0x68, 0x74 }, /* MONGOLIAN LETTER SIBE TA -> 't' */ + { 0x69, 0x64 }, /* MONGOLIAN LETTER SIBE DA -> 'd' */ + { 0x6A, 0x6A }, /* MONGOLIAN LETTER SIBE JA -> 'j' */ + { 0x6B, 0x66 }, /* MONGOLIAN LETTER SIBE FA -> 'f' */ + { 0x6C, 0x67 }, /* MONGOLIAN LETTER SIBE GAA -> 'g' */ + { 0x6D, 0x68 }, /* MONGOLIAN LETTER SIBE HAA -> 'h' */ + { 0x6F, 0x7A }, /* MONGOLIAN LETTER SIBE ZA -> 'z' */ + { 0x70, 0x72 }, /* MONGOLIAN LETTER SIBE RAA -> 'r' */ + { 0x73, 0x69 }, /* MONGOLIAN LETTER MANCHU I -> 'i' */ + { 0x74, 0x6B }, /* MONGOLIAN LETTER MANCHU KA -> 'k' */ + { 0x75, 0x72 }, /* MONGOLIAN LETTER MANCHU RA -> 'r' */ + { 0x76, 0x66 }, /* MONGOLIAN LETTER MANCHU FA -> 'f' */ + { 0x81, 0x48 }, /* MONGOLIAN LETTER ALI GALI VISARGA ONE -> 'H' */ + { 0x82, 0x58 }, /* MONGOLIAN LETTER ALI GALI DAMARU -> 'X' */ + { 0x83, 0x57 }, /* MONGOLIAN LETTER ALI GALI UBADAMA -> 'W' */ + { 0x84, 0x4D }, /* MONGOLIAN LETTER ALI GALI INVERTED UBADAMA -> 'M' */ + { 0x87, 0x61 }, /* MONGOLIAN LETTER ALI GALI A -> 'a' */ + { 0x88, 0x69 }, /* MONGOLIAN LETTER ALI GALI I -> 'i' */ + { 0x89, 0x6B }, /* MONGOLIAN LETTER ALI GALI KA -> 'k' */ + { 0x8B, 0x63 }, /* MONGOLIAN LETTER ALI GALI CA -> 'c' */ + { 0x90, 0x74 }, /* MONGOLIAN LETTER ALI GALI TA -> 't' */ + { 0x91, 0x64 }, /* MONGOLIAN LETTER ALI GALI DA -> 'd' */ + { 0x92, 0x70 }, /* MONGOLIAN LETTER ALI GALI PA -> 'p' */ + { 0x96, 0x7A }, /* MONGOLIAN LETTER ALI GALI ZA -> 'z' */ + { 0x97, 0x61 }, /* MONGOLIAN LETTER ALI GALI AH -> 'a' */ + { 0x98, 0x74 }, /* MONGOLIAN LETTER TODO ALI GALI TA -> 't' */ + { 0x9C, 0x63 }, /* MONGOLIAN LETTER MANCHU ALI GALI CA -> 'c' */ + { 0xA0, 0x74 }, /* MONGOLIAN LETTER MANCHU ALI GALI TA -> 't' */ + { 0xA5, 0x7A }, /* MONGOLIAN LETTER MANCHU ALI GALI ZA -> 'z' */ + { 0xA6, 0x75 }, /* MONGOLIAN LETTER ALI GALI HALF U -> 'u' */ + { 0xA7, 0x79 }, /* MONGOLIAN LETTER ALI GALI HALF YA -> 'y' */ + { 0xA9, 0x27 }, /* MONGOLIAN LETTER ALI GALI DAGALGA -> ''' */ + /* Entries for page 0x1D */ + { 0x00, 0x41 }, /* LATIN LETTER SMALL CAPITAL A -> 'A' */ + { 0x03, 0x42 }, /* LATIN LETTER SMALL CAPITAL BARRED B -> 'B' */ + { 0x04, 0x43 }, /* LATIN LETTER SMALL CAPITAL C -> 'C' */ + { 0x05, 0x44 }, /* LATIN LETTER SMALL CAPITAL D -> 'D' */ + { 0x06, 0x44 }, /* LATIN LETTER SMALL CAPITAL ETH -> 'D' */ + { 0x07, 0x45 }, /* LATIN LETTER SMALL CAPITAL E -> 'E' */ + { 0x08, 0x65 }, /* LATIN SMALL LETTER TURNED OPEN E -> 'e' */ + { 0x09, 0x69 }, /* LATIN SMALL LETTER TURNED I -> 'i' */ + { 0x0A, 0x4A }, /* LATIN LETTER SMALL CAPITAL J -> 'J' */ + { 0x0B, 0x4B }, /* LATIN LETTER SMALL CAPITAL K -> 'K' */ + { 0x0C, 0x4C }, /* LATIN LETTER SMALL CAPITAL L WITH STROKE -> 'L' */ + { 0x0D, 0x4D }, /* LATIN LETTER SMALL CAPITAL M -> 'M' */ + { 0x0E, 0x4E }, /* LATIN LETTER SMALL CAPITAL REVERSED N -> 'N' */ + { 0x0F, 0x4F }, /* LATIN LETTER SMALL CAPITAL O -> 'O' */ + { 0x11, 0x4F }, /* LATIN SMALL LETTER SIDEWAYS O -> 'O' */ + { 0x13, 0x4F }, /* LATIN SMALL LETTER SIDEWAYS O WITH STROKE -> 'O' */ + { 0x18, 0x50 }, /* LATIN LETTER SMALL CAPITAL P -> 'P' */ + { 0x19, 0x52 }, /* LATIN LETTER SMALL CAPITAL REVERSED R -> 'R' */ + { 0x1A, 0x52 }, /* LATIN LETTER SMALL CAPITAL TURNED R -> 'R' */ + { 0x1B, 0x54 }, /* LATIN LETTER SMALL CAPITAL T -> 'T' */ + { 0x1C, 0x55 }, /* LATIN LETTER SMALL CAPITAL U -> 'U' */ + { 0x1D, 0x75 }, /* LATIN SMALL LETTER SIDEWAYS U -> 'u' */ + { 0x1E, 0x75 }, /* LATIN SMALL LETTER SIDEWAYS DIAERESIZED U -> 'u' */ + { 0x1F, 0x6D }, /* LATIN SMALL LETTER SIDEWAYS TURNED M -> 'm' */ + { 0x20, 0x56 }, /* LATIN LETTER SMALL CAPITAL V -> 'V' */ + { 0x21, 0x57 }, /* LATIN LETTER SMALL CAPITAL W -> 'W' */ + { 0x22, 0x5A }, /* LATIN LETTER SMALL CAPITAL Z -> 'Z' */ + { 0x2C, 0x41 }, /* MODIFIER LETTER CAPITAL A -> 'A' */ + { 0x2E, 0x42 }, /* MODIFIER LETTER CAPITAL B -> 'B' */ + { 0x2F, 0x42 }, /* MODIFIER LETTER CAPITAL BARRED B -> 'B' */ + { 0x30, 0x44 }, /* MODIFIER LETTER CAPITAL D -> 'D' */ + { 0x31, 0x45 }, /* MODIFIER LETTER CAPITAL E -> 'E' */ + { 0x32, 0x45 }, /* MODIFIER LETTER CAPITAL REVERSED E -> 'E' */ + { 0x33, 0x47 }, /* MODIFIER LETTER CAPITAL G -> 'G' */ + { 0x34, 0x48 }, /* MODIFIER LETTER CAPITAL H -> 'H' */ + { 0x35, 0x49 }, /* MODIFIER LETTER CAPITAL I -> 'I' */ + { 0x36, 0x4A }, /* MODIFIER LETTER CAPITAL J -> 'J' */ + { 0x37, 0x4B }, /* MODIFIER LETTER CAPITAL K -> 'K' */ + { 0x38, 0x4C }, /* MODIFIER LETTER CAPITAL L -> 'L' */ + { 0x39, 0x4D }, /* MODIFIER LETTER CAPITAL M -> 'M' */ + { 0x3A, 0x4E }, /* MODIFIER LETTER CAPITAL N -> 'N' */ + { 0x3B, 0x4E }, /* MODIFIER LETTER CAPITAL REVERSED N -> 'N' */ + { 0x3C, 0x4F }, /* MODIFIER LETTER CAPITAL O -> 'O' */ + { 0x3E, 0x50 }, /* MODIFIER LETTER CAPITAL P -> 'P' */ + { 0x3F, 0x52 }, /* MODIFIER LETTER CAPITAL R -> 'R' */ + { 0x40, 0x54 }, /* MODIFIER LETTER CAPITAL T -> 'T' */ + { 0x41, 0x55 }, /* MODIFIER LETTER CAPITAL U -> 'U' */ + { 0x42, 0x57 }, /* MODIFIER LETTER CAPITAL W -> 'W' */ + { 0x43, 0x00 }, /* MODIFIER LETTER SMALL A -> ... */ + { 0x45, 0x61 }, /* MODIFIER LETTER SMALL ALPHA -> 'a' */ + { 0x47, 0x62 }, /* MODIFIER LETTER SMALL B -> 'b' */ + { 0x48, 0x64 }, /* MODIFIER LETTER SMALL D -> 'd' */ + { 0x49, 0x65 }, /* MODIFIER LETTER SMALL E -> 'e' */ + { 0x4B, 0x65 }, /* MODIFIER LETTER SMALL OPEN E -> 'e' */ + { 0x4C, 0x65 }, /* MODIFIER LETTER SMALL TURNED OPEN E -> 'e' */ + { 0x4D, 0x67 }, /* MODIFIER LETTER SMALL G -> 'g' */ + { 0x4E, 0x69 }, /* MODIFIER LETTER SMALL TURNED I -> 'i' */ + { 0x4F, 0x6B }, /* MODIFIER LETTER SMALL K -> 'k' */ + { 0x50, 0x6D }, /* MODIFIER LETTER SMALL M -> 'm' */ + { 0x52, 0x6F }, /* MODIFIER LETTER SMALL O -> 'o' */ + { 0x56, 0x70 }, /* MODIFIER LETTER SMALL P -> 'p' */ + { 0x57, 0x74 }, /* MODIFIER LETTER SMALL T -> 't' */ + { 0x58, 0x75 }, /* MODIFIER LETTER SMALL U -> 'u' */ + { 0x59, 0x75 }, /* MODIFIER LETTER SMALL SIDEWAYS U -> 'u' */ + { 0x5A, 0x6D }, /* MODIFIER LETTER SMALL TURNED M -> 'm' */ + { 0x5B, 0x76 }, /* MODIFIER LETTER SMALL V -> 'v' */ + { 0x5D, 0x62 }, /* MODIFIER LETTER SMALL BETA -> 'b' */ + { 0x5E, 0x67 }, /* MODIFIER LETTER SMALL GREEK GAMMA -> 'g' */ + { 0x5F, 0x64 }, /* MODIFIER LETTER SMALL DELTA -> 'd' */ + { 0x60, 0x66 }, /* MODIFIER LETTER SMALL GREEK PHI -> 'f' */ + { 0x62, 0x69 }, /* LATIN SUBSCRIPT SMALL LETTER I -> 'i' */ + { 0x63, 0x72 }, /* LATIN SUBSCRIPT SMALL LETTER R -> 'r' */ + { 0x64, 0x75 }, /* LATIN SUBSCRIPT SMALL LETTER U -> 'u' */ + { 0x65, 0x76 }, /* LATIN SUBSCRIPT SMALL LETTER V -> 'v' */ + { 0x66, 0x62 }, /* GREEK SUBSCRIPT SMALL LETTER BETA -> 'b' */ + { 0x67, 0x67 }, /* GREEK SUBSCRIPT SMALL LETTER GAMMA -> 'g' */ + { 0x68, 0x72 }, /* GREEK SUBSCRIPT SMALL LETTER RHO -> 'r' */ + { 0x69, 0x66 }, /* GREEK SUBSCRIPT SMALL LETTER PHI -> 'f' */ + { 0x6C, 0x62 }, /* LATIN SMALL LETTER B WITH MIDDLE TILDE -> 'b' */ + { 0x6D, 0x64 }, /* LATIN SMALL LETTER D WITH MIDDLE TILDE -> 'd' */ + { 0x6E, 0x66 }, /* LATIN SMALL LETTER F WITH MIDDLE TILDE -> 'f' */ + { 0x6F, 0x6D }, /* LATIN SMALL LETTER M WITH MIDDLE TILDE -> 'm' */ + { 0x70, 0x6E }, /* LATIN SMALL LETTER N WITH MIDDLE TILDE -> 'n' */ + { 0x71, 0x70 }, /* LATIN SMALL LETTER P WITH MIDDLE TILDE -> 'p' */ + { 0x72, 0x72 }, /* LATIN SMALL LETTER R WITH MIDDLE TILDE -> 'r' */ + { 0x73, 0x72 }, /* LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE -> 'r' */ + { 0x74, 0x73 }, /* LATIN SMALL LETTER S WITH MIDDLE TILDE -> 's' */ + { 0x75, 0x74 }, /* LATIN SMALL LETTER T WITH MIDDLE TILDE -> 't' */ + { 0x76, 0x7A }, /* LATIN SMALL LETTER Z WITH MIDDLE TILDE -> 'z' */ + { 0x77, 0x67 }, /* LATIN SMALL LETTER TURNED G -> 'g' */ + { 0x7D, 0x70 }, /* LATIN SMALL LETTER P WITH STROKE -> 'p' */ + { 0x80, 0x62 }, /* LATIN SMALL LETTER B WITH PALATAL HOOK -> 'b' */ + { 0x81, 0x64 }, /* LATIN SMALL LETTER D WITH PALATAL HOOK -> 'd' */ + { 0x82, 0x66 }, /* LATIN SMALL LETTER F WITH PALATAL HOOK -> 'f' */ + { 0x83, 0x67 }, /* LATIN SMALL LETTER G WITH PALATAL HOOK -> 'g' */ + { 0x84, 0x6B }, /* LATIN SMALL LETTER K WITH PALATAL HOOK -> 'k' */ + { 0x85, 0x6C }, /* LATIN SMALL LETTER L WITH PALATAL HOOK -> 'l' */ + { 0x86, 0x6D }, /* LATIN SMALL LETTER M WITH PALATAL HOOK -> 'm' */ + { 0x87, 0x6E }, /* LATIN SMALL LETTER N WITH PALATAL HOOK -> 'n' */ + { 0x88, 0x70 }, /* LATIN SMALL LETTER P WITH PALATAL HOOK -> 'p' */ + { 0x89, 0x72 }, /* LATIN SMALL LETTER R WITH PALATAL HOOK -> 'r' */ + { 0x8A, 0x73 }, /* LATIN SMALL LETTER S WITH PALATAL HOOK -> 's' */ + { 0x8C, 0x76 }, /* LATIN SMALL LETTER V WITH PALATAL HOOK -> 'v' */ + { 0x8D, 0x78 }, /* LATIN SMALL LETTER X WITH PALATAL HOOK -> 'x' */ + { 0x8E, 0x7A }, /* LATIN SMALL LETTER Z WITH PALATAL HOOK -> 'z' */ + /* Entries for page 0x1E */ + { 0x00, 0x41 }, /* LATIN CAPITAL LETTER A WITH RING BELOW -> 'A' */ + { 0x01, 0x61 }, /* LATIN SMALL LETTER A WITH RING BELOW -> 'a' */ + { 0x02, 0x42 }, /* LATIN CAPITAL LETTER B WITH DOT ABOVE -> 'B' */ + { 0x03, 0x62 }, /* LATIN SMALL LETTER B WITH DOT ABOVE -> 'b' */ + { 0x04, 0x42 }, /* LATIN CAPITAL LETTER B WITH DOT BELOW -> 'B' */ + { 0x05, 0x62 }, /* LATIN SMALL LETTER B WITH DOT BELOW -> 'b' */ + { 0x06, 0x42 }, /* LATIN CAPITAL LETTER B WITH LINE BELOW -> 'B' */ + { 0x07, 0x62 }, /* LATIN SMALL LETTER B WITH LINE BELOW -> 'b' */ + { 0x08, 0x43 }, /* LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE -> 'C' */ + { 0x09, 0x63 }, /* LATIN SMALL LETTER C WITH CEDILLA AND ACUTE -> 'c' */ + { 0x0A, 0x44 }, /* LATIN CAPITAL LETTER D WITH DOT ABOVE -> 'D' */ + { 0x0B, 0x64 }, /* LATIN SMALL LETTER D WITH DOT ABOVE -> 'd' */ + { 0x0C, 0x44 }, /* LATIN CAPITAL LETTER D WITH DOT BELOW -> 'D' */ + { 0x0D, 0x64 }, /* LATIN SMALL LETTER D WITH DOT BELOW -> 'd' */ + { 0x0E, 0x44 }, /* LATIN CAPITAL LETTER D WITH LINE BELOW -> 'D' */ + { 0x0F, 0x64 }, /* LATIN SMALL LETTER D WITH LINE BELOW -> 'd' */ + { 0x10, 0x44 }, /* LATIN CAPITAL LETTER D WITH CEDILLA -> 'D' */ + { 0x11, 0x64 }, /* LATIN SMALL LETTER D WITH CEDILLA -> 'd' */ + { 0x12, 0x44 }, /* LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW -> 'D' */ + { 0x13, 0x64 }, /* LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW -> 'd' */ + { 0x14, 0x45 }, /* LATIN CAPITAL LETTER E WITH MACRON AND GRAVE -> 'E' */ + { 0x15, 0x65 }, /* LATIN SMALL LETTER E WITH MACRON AND GRAVE -> 'e' */ + { 0x16, 0x45 }, /* LATIN CAPITAL LETTER E WITH MACRON AND ACUTE -> 'E' */ + { 0x17, 0x65 }, /* LATIN SMALL LETTER E WITH MACRON AND ACUTE -> 'e' */ + { 0x18, 0x45 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW -> 'E' */ + { 0x19, 0x65 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW -> 'e' */ + { 0x1A, 0x45 }, /* LATIN CAPITAL LETTER E WITH TILDE BELOW -> 'E' */ + { 0x1B, 0x65 }, /* LATIN SMALL LETTER E WITH TILDE BELOW -> 'e' */ + { 0x1C, 0x45 }, /* LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE -> 'E' */ + { 0x1D, 0x65 }, /* LATIN SMALL LETTER E WITH CEDILLA AND BREVE -> 'e' */ + { 0x1E, 0x46 }, /* LATIN CAPITAL LETTER F WITH DOT ABOVE -> 'F' */ + { 0x1F, 0x66 }, /* LATIN SMALL LETTER F WITH DOT ABOVE -> 'f' */ + { 0x20, 0x47 }, /* LATIN CAPITAL LETTER G WITH MACRON -> 'G' */ + { 0x21, 0x67 }, /* LATIN SMALL LETTER G WITH MACRON -> 'g' */ + { 0x22, 0x48 }, /* LATIN CAPITAL LETTER H WITH DOT ABOVE -> 'H' */ + { 0x23, 0x68 }, /* LATIN SMALL LETTER H WITH DOT ABOVE -> 'h' */ + { 0x24, 0x48 }, /* LATIN CAPITAL LETTER H WITH DOT BELOW -> 'H' */ + { 0x25, 0x68 }, /* LATIN SMALL LETTER H WITH DOT BELOW -> 'h' */ + { 0x26, 0x48 }, /* LATIN CAPITAL LETTER H WITH DIAERESIS -> 'H' */ + { 0x27, 0x68 }, /* LATIN SMALL LETTER H WITH DIAERESIS -> 'h' */ + { 0x28, 0x48 }, /* LATIN CAPITAL LETTER H WITH CEDILLA -> 'H' */ + { 0x29, 0x68 }, /* LATIN SMALL LETTER H WITH CEDILLA -> 'h' */ + { 0x2A, 0x48 }, /* LATIN CAPITAL LETTER H WITH BREVE BELOW -> 'H' */ + { 0x2B, 0x68 }, /* LATIN SMALL LETTER H WITH BREVE BELOW -> 'h' */ + { 0x2C, 0x49 }, /* LATIN CAPITAL LETTER I WITH TILDE BELOW -> 'I' */ + { 0x2D, 0x69 }, /* LATIN SMALL LETTER I WITH TILDE BELOW -> 'i' */ + { 0x2E, 0x49 }, /* LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE -> 'I' */ + { 0x2F, 0x69 }, /* LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE -> 'i' */ + { 0x30, 0x4B }, /* LATIN CAPITAL LETTER K WITH ACUTE -> 'K' */ + { 0x31, 0x6B }, /* LATIN SMALL LETTER K WITH ACUTE -> 'k' */ + { 0x32, 0x4B }, /* LATIN CAPITAL LETTER K WITH DOT BELOW -> 'K' */ + { 0x33, 0x6B }, /* LATIN SMALL LETTER K WITH DOT BELOW -> 'k' */ + { 0x34, 0x4B }, /* LATIN CAPITAL LETTER K WITH LINE BELOW -> 'K' */ + { 0x35, 0x6B }, /* LATIN SMALL LETTER K WITH LINE BELOW -> 'k' */ + { 0x36, 0x4C }, /* LATIN CAPITAL LETTER L WITH DOT BELOW -> 'L' */ + { 0x37, 0x6C }, /* LATIN SMALL LETTER L WITH DOT BELOW -> 'l' */ + { 0x38, 0x4C }, /* LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON -> 'L' */ + { 0x39, 0x6C }, /* LATIN SMALL LETTER L WITH DOT BELOW AND MACRON -> 'l' */ + { 0x3A, 0x4C }, /* LATIN CAPITAL LETTER L WITH LINE BELOW -> 'L' */ + { 0x3B, 0x6C }, /* LATIN SMALL LETTER L WITH LINE BELOW -> 'l' */ + { 0x3C, 0x4C }, /* LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW -> 'L' */ + { 0x3D, 0x6C }, /* LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW -> 'l' */ + { 0x3E, 0x4D }, /* LATIN CAPITAL LETTER M WITH ACUTE -> 'M' */ + { 0x3F, 0x6D }, /* LATIN SMALL LETTER M WITH ACUTE -> 'm' */ + { 0x40, 0x4D }, /* LATIN CAPITAL LETTER M WITH DOT ABOVE -> 'M' */ + { 0x41, 0x6D }, /* LATIN SMALL LETTER M WITH DOT ABOVE -> 'm' */ + { 0x42, 0x4D }, /* LATIN CAPITAL LETTER M WITH DOT BELOW -> 'M' */ + { 0x43, 0x6D }, /* LATIN SMALL LETTER M WITH DOT BELOW -> 'm' */ + { 0x44, 0x4E }, /* LATIN CAPITAL LETTER N WITH DOT ABOVE -> 'N' */ + { 0x45, 0x6E }, /* LATIN SMALL LETTER N WITH DOT ABOVE -> 'n' */ + { 0x46, 0x4E }, /* LATIN CAPITAL LETTER N WITH DOT BELOW -> 'N' */ + { 0x47, 0x6E }, /* LATIN SMALL LETTER N WITH DOT BELOW -> 'n' */ + { 0x48, 0x4E }, /* LATIN CAPITAL LETTER N WITH LINE BELOW -> 'N' */ + { 0x49, 0x6E }, /* LATIN SMALL LETTER N WITH LINE BELOW -> 'n' */ + { 0x4A, 0x4E }, /* LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW -> 'N' */ + { 0x4B, 0x6E }, /* LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW -> 'n' */ + { 0x4C, 0x4F }, /* LATIN CAPITAL LETTER O WITH TILDE AND ACUTE -> 'O' */ + { 0x4D, 0x6F }, /* LATIN SMALL LETTER O WITH TILDE AND ACUTE -> 'o' */ + { 0x4E, 0x4F }, /* LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS -> 'O' */ + { 0x4F, 0x6F }, /* LATIN SMALL LETTER O WITH TILDE AND DIAERESIS -> 'o' */ + { 0x50, 0x4F }, /* LATIN CAPITAL LETTER O WITH MACRON AND GRAVE -> 'O' */ + { 0x51, 0x6F }, /* LATIN SMALL LETTER O WITH MACRON AND GRAVE -> 'o' */ + { 0x52, 0x4F }, /* LATIN CAPITAL LETTER O WITH MACRON AND ACUTE -> 'O' */ + { 0x53, 0x6F }, /* LATIN SMALL LETTER O WITH MACRON AND ACUTE -> 'o' */ + { 0x54, 0x50 }, /* LATIN CAPITAL LETTER P WITH ACUTE -> 'P' */ + { 0x55, 0x70 }, /* LATIN SMALL LETTER P WITH ACUTE -> 'p' */ + { 0x56, 0x50 }, /* LATIN CAPITAL LETTER P WITH DOT ABOVE -> 'P' */ + { 0x57, 0x70 }, /* LATIN SMALL LETTER P WITH DOT ABOVE -> 'p' */ + { 0x58, 0x52 }, /* LATIN CAPITAL LETTER R WITH DOT ABOVE -> 'R' */ + { 0x59, 0x72 }, /* LATIN SMALL LETTER R WITH DOT ABOVE -> 'r' */ + { 0x5A, 0x52 }, /* LATIN CAPITAL LETTER R WITH DOT BELOW -> 'R' */ + { 0x5B, 0x72 }, /* LATIN SMALL LETTER R WITH DOT BELOW -> 'r' */ + { 0x5C, 0x52 }, /* LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON -> 'R' */ + { 0x5D, 0x72 }, /* LATIN SMALL LETTER R WITH DOT BELOW AND MACRON -> 'r' */ + { 0x5E, 0x52 }, /* LATIN CAPITAL LETTER R WITH LINE BELOW -> 'R' */ + { 0x5F, 0x72 }, /* LATIN SMALL LETTER R WITH LINE BELOW -> 'r' */ + { 0x60, 0x53 }, /* LATIN CAPITAL LETTER S WITH DOT ABOVE -> 'S' */ + { 0x61, 0x73 }, /* LATIN SMALL LETTER S WITH DOT ABOVE -> 's' */ + { 0x62, 0x53 }, /* LATIN CAPITAL LETTER S WITH DOT BELOW -> 'S' */ + { 0x63, 0x73 }, /* LATIN SMALL LETTER S WITH DOT BELOW -> 's' */ + { 0x64, 0x53 }, /* LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE -> 'S' */ + { 0x65, 0x73 }, /* LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE -> 's' */ + { 0x66, 0x53 }, /* LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE -> 'S' */ + { 0x67, 0x73 }, /* LATIN SMALL LETTER S WITH CARON AND DOT ABOVE -> 's' */ + { 0x68, 0x53 }, /* LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE -> 'S' */ + { 0x69, 0x73 }, /* LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE -> 's' */ + { 0x6A, 0x54 }, /* LATIN CAPITAL LETTER T WITH DOT ABOVE -> 'T' */ + { 0x6B, 0x74 }, /* LATIN SMALL LETTER T WITH DOT ABOVE -> 't' */ + { 0x6C, 0x54 }, /* LATIN CAPITAL LETTER T WITH DOT BELOW -> 'T' */ + { 0x6D, 0x74 }, /* LATIN SMALL LETTER T WITH DOT BELOW -> 't' */ + { 0x6E, 0x54 }, /* LATIN CAPITAL LETTER T WITH LINE BELOW -> 'T' */ + { 0x6F, 0x74 }, /* LATIN SMALL LETTER T WITH LINE BELOW -> 't' */ + { 0x70, 0x54 }, /* LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW -> 'T' */ + { 0x71, 0x74 }, /* LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW -> 't' */ + { 0x72, 0x55 }, /* LATIN CAPITAL LETTER U WITH DIAERESIS BELOW -> 'U' */ + { 0x73, 0x75 }, /* LATIN SMALL LETTER U WITH DIAERESIS BELOW -> 'u' */ + { 0x74, 0x55 }, /* LATIN CAPITAL LETTER U WITH TILDE BELOW -> 'U' */ + { 0x75, 0x75 }, /* LATIN SMALL LETTER U WITH TILDE BELOW -> 'u' */ + { 0x76, 0x55 }, /* LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW -> 'U' */ + { 0x77, 0x75 }, /* LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW -> 'u' */ + { 0x78, 0x55 }, /* LATIN CAPITAL LETTER U WITH TILDE AND ACUTE -> 'U' */ + { 0x79, 0x75 }, /* LATIN SMALL LETTER U WITH TILDE AND ACUTE -> 'u' */ + { 0x7A, 0x55 }, /* LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS -> 'U' */ + { 0x7B, 0x75 }, /* LATIN SMALL LETTER U WITH MACRON AND DIAERESIS -> 'u' */ + { 0x7C, 0x56 }, /* LATIN CAPITAL LETTER V WITH TILDE -> 'V' */ + { 0x7D, 0x76 }, /* LATIN SMALL LETTER V WITH TILDE -> 'v' */ + { 0x7E, 0x56 }, /* LATIN CAPITAL LETTER V WITH DOT BELOW -> 'V' */ + { 0x7F, 0x76 }, /* LATIN SMALL LETTER V WITH DOT BELOW -> 'v' */ + { 0x80, 0x57 }, /* LATIN CAPITAL LETTER W WITH GRAVE -> 'W' */ + { 0x81, 0x77 }, /* LATIN SMALL LETTER W WITH GRAVE -> 'w' */ + { 0x82, 0x57 }, /* LATIN CAPITAL LETTER W WITH ACUTE -> 'W' */ + { 0x83, 0x77 }, /* LATIN SMALL LETTER W WITH ACUTE -> 'w' */ + { 0x84, 0x57 }, /* LATIN CAPITAL LETTER W WITH DIAERESIS -> 'W' */ + { 0x85, 0x77 }, /* LATIN SMALL LETTER W WITH DIAERESIS -> 'w' */ + { 0x86, 0x57 }, /* LATIN CAPITAL LETTER W WITH DOT ABOVE -> 'W' */ + { 0x87, 0x77 }, /* LATIN SMALL LETTER W WITH DOT ABOVE -> 'w' */ + { 0x88, 0x57 }, /* LATIN CAPITAL LETTER W WITH DOT BELOW -> 'W' */ + { 0x89, 0x77 }, /* LATIN SMALL LETTER W WITH DOT BELOW -> 'w' */ + { 0x8A, 0x58 }, /* LATIN CAPITAL LETTER X WITH DOT ABOVE -> 'X' */ + { 0x8B, 0x78 }, /* LATIN SMALL LETTER X WITH DOT ABOVE -> 'x' */ + { 0x8C, 0x58 }, /* LATIN CAPITAL LETTER X WITH DIAERESIS -> 'X' */ + { 0x8D, 0x78 }, /* LATIN SMALL LETTER X WITH DIAERESIS -> 'x' */ + { 0x8E, 0x59 }, /* LATIN CAPITAL LETTER Y WITH DOT ABOVE -> 'Y' */ + { 0x8F, 0x79 }, /* LATIN SMALL LETTER Y WITH DOT ABOVE -> 'y' */ + { 0x90, 0x5A }, /* LATIN CAPITAL LETTER Z WITH CIRCUMFLEX -> 'Z' */ + { 0x91, 0x7A }, /* LATIN SMALL LETTER Z WITH CIRCUMFLEX -> 'z' */ + { 0x92, 0x5A }, /* LATIN CAPITAL LETTER Z WITH DOT BELOW -> 'Z' */ + { 0x93, 0x7A }, /* LATIN SMALL LETTER Z WITH DOT BELOW -> 'z' */ + { 0x94, 0x5A }, /* LATIN CAPITAL LETTER Z WITH LINE BELOW -> 'Z' */ + { 0x95, 0x7A }, /* LATIN SMALL LETTER Z WITH LINE BELOW -> 'z' */ + { 0x96, 0x68 }, /* LATIN SMALL LETTER H WITH LINE BELOW -> 'h' */ + { 0x97, 0x74 }, /* LATIN SMALL LETTER T WITH DIAERESIS -> 't' */ + { 0x98, 0x77 }, /* LATIN SMALL LETTER W WITH RING ABOVE -> 'w' */ + { 0x99, 0x79 }, /* LATIN SMALL LETTER Y WITH RING ABOVE -> 'y' */ + { 0x9A, 0x61 }, /* LATIN SMALL LETTER A WITH RIGHT HALF RING -> 'a' */ + { 0x9B, 0x53 }, /* LATIN SMALL LETTER LONG S WITH DOT ABOVE -> 'S' */ + { 0xA0, 0x41 }, /* LATIN CAPITAL LETTER A WITH DOT BELOW -> 'A' */ + { 0xA1, 0x61 }, /* LATIN SMALL LETTER A WITH DOT BELOW -> 'a' */ + { 0xA2, 0x41 }, /* LATIN CAPITAL LETTER A WITH HOOK ABOVE -> 'A' */ + { 0xA3, 0x61 }, /* LATIN SMALL LETTER A WITH HOOK ABOVE -> 'a' */ + { 0xA4, 0x41 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE -> 'A' */ + { 0xA5, 0x61 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE -> 'a' */ + { 0xA6, 0x41 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE -> 'A' */ + { 0xA7, 0x61 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE -> 'a' */ + { 0xA8, 0x41 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE -> 'A' */ + { 0xA9, 0x61 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE -> 'a' */ + { 0xAA, 0x41 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE -> 'A' */ + { 0xAB, 0x61 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE -> 'a' */ + { 0xAC, 0x41 }, /* LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW -> 'A' */ + { 0xAD, 0x61 }, /* LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW -> 'a' */ + { 0xAE, 0x41 }, /* LATIN CAPITAL LETTER A WITH BREVE AND ACUTE -> 'A' */ + { 0xAF, 0x61 }, /* LATIN SMALL LETTER A WITH BREVE AND ACUTE -> 'a' */ + { 0xB0, 0x41 }, /* LATIN CAPITAL LETTER A WITH BREVE AND GRAVE -> 'A' */ + { 0xB1, 0x61 }, /* LATIN SMALL LETTER A WITH BREVE AND GRAVE -> 'a' */ + { 0xB2, 0x41 }, /* LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE -> 'A' */ + { 0xB3, 0x61 }, /* LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE -> 'a' */ + { 0xB4, 0x41 }, /* LATIN CAPITAL LETTER A WITH BREVE AND TILDE -> 'A' */ + { 0xB5, 0x61 }, /* LATIN SMALL LETTER A WITH BREVE AND TILDE -> 'a' */ + { 0xB6, 0x41 }, /* LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW -> 'A' */ + { 0xB7, 0x61 }, /* LATIN SMALL LETTER A WITH BREVE AND DOT BELOW -> 'a' */ + { 0xB8, 0x45 }, /* LATIN CAPITAL LETTER E WITH DOT BELOW -> 'E' */ + { 0xB9, 0x65 }, /* LATIN SMALL LETTER E WITH DOT BELOW -> 'e' */ + { 0xBA, 0x45 }, /* LATIN CAPITAL LETTER E WITH HOOK ABOVE -> 'E' */ + { 0xBB, 0x65 }, /* LATIN SMALL LETTER E WITH HOOK ABOVE -> 'e' */ + { 0xBC, 0x45 }, /* LATIN CAPITAL LETTER E WITH TILDE -> 'E' */ + { 0xBD, 0x65 }, /* LATIN SMALL LETTER E WITH TILDE -> 'e' */ + { 0xBE, 0x45 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE -> 'E' */ + { 0xBF, 0x65 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE -> 'e' */ + { 0xC0, 0x45 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE -> 'E' */ + { 0xC1, 0x65 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE -> 'e' */ + { 0xC2, 0x45 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE -> 'E' */ + { 0xC3, 0x65 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE -> 'e' */ + { 0xC4, 0x45 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE -> 'E' */ + { 0xC5, 0x65 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE -> 'e' */ + { 0xC6, 0x45 }, /* LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW -> 'E' */ + { 0xC7, 0x65 }, /* LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW -> 'e' */ + { 0xC8, 0x49 }, /* LATIN CAPITAL LETTER I WITH HOOK ABOVE -> 'I' */ + { 0xC9, 0x69 }, /* LATIN SMALL LETTER I WITH HOOK ABOVE -> 'i' */ + { 0xCA, 0x49 }, /* LATIN CAPITAL LETTER I WITH DOT BELOW -> 'I' */ + { 0xCB, 0x69 }, /* LATIN SMALL LETTER I WITH DOT BELOW -> 'i' */ + { 0xCC, 0x4F }, /* LATIN CAPITAL LETTER O WITH DOT BELOW -> 'O' */ + { 0xCD, 0x6F }, /* LATIN SMALL LETTER O WITH DOT BELOW -> 'o' */ + { 0xCE, 0x4F }, /* LATIN CAPITAL LETTER O WITH HOOK ABOVE -> 'O' */ + { 0xCF, 0x6F }, /* LATIN SMALL LETTER O WITH HOOK ABOVE -> 'o' */ + { 0xD0, 0x4F }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE -> 'O' */ + { 0xD1, 0x6F }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE -> 'o' */ + { 0xD2, 0x4F }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE -> 'O' */ + { 0xD3, 0x6F }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE -> 'o' */ + { 0xD4, 0x4F }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE -> 'O' */ + { 0xD5, 0x6F }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE -> 'o' */ + { 0xD6, 0x4F }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE -> 'O' */ + { 0xD7, 0x6F }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE -> 'o' */ + { 0xD8, 0x4F }, /* LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW -> 'O' */ + { 0xD9, 0x6F }, /* LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW -> 'o' */ + { 0xDA, 0x4F }, /* LATIN CAPITAL LETTER O WITH HORN AND ACUTE -> 'O' */ + { 0xDB, 0x6F }, /* LATIN SMALL LETTER O WITH HORN AND ACUTE -> 'o' */ + { 0xDC, 0x4F }, /* LATIN CAPITAL LETTER O WITH HORN AND GRAVE -> 'O' */ + { 0xDD, 0x6F }, /* LATIN SMALL LETTER O WITH HORN AND GRAVE -> 'o' */ + { 0xDE, 0x4F }, /* LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE -> 'O' */ + { 0xDF, 0x6F }, /* LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE -> 'o' */ + { 0xE0, 0x4F }, /* LATIN CAPITAL LETTER O WITH HORN AND TILDE -> 'O' */ + { 0xE1, 0x6F }, /* LATIN SMALL LETTER O WITH HORN AND TILDE -> 'o' */ + { 0xE2, 0x4F }, /* LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW -> 'O' */ + { 0xE3, 0x6F }, /* LATIN SMALL LETTER O WITH HORN AND DOT BELOW -> 'o' */ + { 0xE4, 0x55 }, /* LATIN CAPITAL LETTER U WITH DOT BELOW -> 'U' */ + { 0xE5, 0x75 }, /* LATIN SMALL LETTER U WITH DOT BELOW -> 'u' */ + { 0xE6, 0x55 }, /* LATIN CAPITAL LETTER U WITH HOOK ABOVE -> 'U' */ + { 0xE7, 0x75 }, /* LATIN SMALL LETTER U WITH HOOK ABOVE -> 'u' */ + { 0xE8, 0x55 }, /* LATIN CAPITAL LETTER U WITH HORN AND ACUTE -> 'U' */ + { 0xE9, 0x75 }, /* LATIN SMALL LETTER U WITH HORN AND ACUTE -> 'u' */ + { 0xEA, 0x55 }, /* LATIN CAPITAL LETTER U WITH HORN AND GRAVE -> 'U' */ + { 0xEB, 0x75 }, /* LATIN SMALL LETTER U WITH HORN AND GRAVE -> 'u' */ + { 0xEC, 0x55 }, /* LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE -> 'U' */ + { 0xED, 0x75 }, /* LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE -> 'u' */ + { 0xEE, 0x55 }, /* LATIN CAPITAL LETTER U WITH HORN AND TILDE -> 'U' */ + { 0xEF, 0x75 }, /* LATIN SMALL LETTER U WITH HORN AND TILDE -> 'u' */ + { 0xF0, 0x55 }, /* LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW -> 'U' */ + { 0xF1, 0x75 }, /* LATIN SMALL LETTER U WITH HORN AND DOT BELOW -> 'u' */ + { 0xF2, 0x59 }, /* LATIN CAPITAL LETTER Y WITH GRAVE -> 'Y' */ + { 0xF3, 0x79 }, /* LATIN SMALL LETTER Y WITH GRAVE -> 'y' */ + { 0xF4, 0x59 }, /* LATIN CAPITAL LETTER Y WITH DOT BELOW -> 'Y' */ + { 0xF5, 0x79 }, /* LATIN SMALL LETTER Y WITH DOT BELOW -> 'y' */ + { 0xF6, 0x59 }, /* LATIN CAPITAL LETTER Y WITH HOOK ABOVE -> 'Y' */ + { 0xF7, 0x79 }, /* LATIN SMALL LETTER Y WITH HOOK ABOVE -> 'y' */ + { 0xF8, 0x59 }, /* LATIN CAPITAL LETTER Y WITH TILDE -> 'Y' */ + { 0xF9, 0x79 }, /* LATIN SMALL LETTER Y WITH TILDE -> 'y' */ + /* Entries for page 0x1F */ + { 0x00, 0x00 }, /* GREEK SMALL LETTER ALPHA WITH PSILI -> ... */ + { 0x07, 0x61 }, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI -> 'a' */ + { 0x08, 0x00 }, /* GREEK CAPITAL LETTER ALPHA WITH PSILI -> ... */ + { 0x0F, 0x41 }, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI -> 'A' */ + { 0x10, 0x00 }, /* GREEK SMALL LETTER EPSILON WITH PSILI -> ... */ + { 0x15, 0x65 }, /* GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA -> 'e' */ + { 0x18, 0x00 }, /* GREEK CAPITAL LETTER EPSILON WITH PSILI -> ... */ + { 0x1D, 0x45 }, /* GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA -> 'E' */ + { 0x20, 0x00 }, /* GREEK SMALL LETTER ETA WITH PSILI -> ... */ + { 0x27, 0x65 }, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI -> 'e' */ + { 0x28, 0x00 }, /* GREEK CAPITAL LETTER ETA WITH PSILI -> ... */ + { 0x2F, 0x45 }, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI -> 'E' */ + { 0x30, 0x00 }, /* GREEK SMALL LETTER IOTA WITH PSILI -> ... */ + { 0x37, 0x69 }, /* GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI -> 'i' */ + { 0x38, 0x00 }, /* GREEK CAPITAL LETTER IOTA WITH PSILI -> ... */ + { 0x3F, 0x49 }, /* GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI -> 'I' */ + { 0x40, 0x00 }, /* GREEK SMALL LETTER OMICRON WITH PSILI -> ... */ + { 0x45, 0x6F }, /* GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA -> 'o' */ + { 0x48, 0x00 }, /* GREEK CAPITAL LETTER OMICRON WITH PSILI -> ... */ + { 0x4D, 0x4F }, /* GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA -> 'O' */ + { 0x50, 0x00 }, /* GREEK SMALL LETTER UPSILON WITH PSILI -> ... */ + { 0x57, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI -> 'u' */ + { 0x59, 0x55 }, /* GREEK CAPITAL LETTER UPSILON WITH DASIA -> 'U' */ + { 0x5B, 0x55 }, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA -> 'U' */ + { 0x5D, 0x55 }, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA -> 'U' */ + { 0x5F, 0x55 }, /* GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI -> 'U' */ + { 0x60, 0x00 }, /* GREEK SMALL LETTER OMEGA WITH PSILI -> ... */ + { 0x67, 0x6F }, /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI -> 'o' */ + { 0x68, 0x00 }, /* GREEK CAPITAL LETTER OMEGA WITH PSILI -> ... */ + { 0x6F, 0x4F }, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI -> 'O' */ + { 0x70, 0x61 }, /* GREEK SMALL LETTER ALPHA WITH VARIA -> 'a' */ + { 0x71, 0x61 }, /* GREEK SMALL LETTER ALPHA WITH OXIA -> 'a' */ + { 0x72, 0x00 }, /* GREEK SMALL LETTER EPSILON WITH VARIA -> ... */ + { 0x75, 0x65 }, /* GREEK SMALL LETTER ETA WITH OXIA -> 'e' */ + { 0x76, 0x69 }, /* GREEK SMALL LETTER IOTA WITH VARIA -> 'i' */ + { 0x77, 0x69 }, /* GREEK SMALL LETTER IOTA WITH OXIA -> 'i' */ + { 0x78, 0x6F }, /* GREEK SMALL LETTER OMICRON WITH VARIA -> 'o' */ + { 0x79, 0x6F }, /* GREEK SMALL LETTER OMICRON WITH OXIA -> 'o' */ + { 0x7A, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH VARIA -> 'u' */ + { 0x7B, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH OXIA -> 'u' */ + { 0x7C, 0x6F }, /* GREEK SMALL LETTER OMEGA WITH VARIA -> 'o' */ + { 0x7D, 0x6F }, /* GREEK SMALL LETTER OMEGA WITH OXIA -> 'o' */ + { 0x80, 0x00 }, /* GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI -> ... */ + { 0x87, 0x61 }, /* GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -> 'a' */ + { 0x88, 0x00 }, /* GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI -> ... */ + { 0x8F, 0x41 }, /* GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -> 'A' */ + { 0x90, 0x00 }, /* GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI -> ... */ + { 0x97, 0x65 }, /* GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -> 'e' */ + { 0x98, 0x00 }, /* GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI -> ... */ + { 0x9F, 0x45 }, /* GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -> 'E' */ + { 0xA0, 0x00 }, /* GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI -> ... */ + { 0xA7, 0x6F }, /* GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI -> 'o' */ + { 0xA8, 0x00 }, /* GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI -> ... */ + { 0xAF, 0x4F }, /* GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI -> 'O' */ + { 0xB0, 0x00 }, /* GREEK SMALL LETTER ALPHA WITH VRACHY -> ... */ + { 0xB4, 0x61 }, /* GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI -> 'a' */ + { 0xB6, 0x61 }, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI -> 'a' */ + { 0xB7, 0x61 }, /* GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI -> 'a' */ + { 0xB8, 0x00 }, /* GREEK CAPITAL LETTER ALPHA WITH VRACHY -> ... */ + { 0xBC, 0x41 }, /* GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI -> 'A' */ + { 0xBD, 0x27 }, /* GREEK KORONIS -> ''' */ + { 0xBE, 0x69 }, /* GREEK PROSGEGRAMMENI -> 'i' */ + { 0xBF, 0x27 }, /* GREEK PSILI -> ''' */ + { 0xC0, 0x7E }, /* GREEK PERISPOMENI -> '~' */ + { 0xC2, 0x00 }, /* GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI -> ... */ + { 0xC4, 0x65 }, /* GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI -> 'e' */ + { 0xC6, 0x65 }, /* GREEK SMALL LETTER ETA WITH PERISPOMENI -> 'e' */ + { 0xC7, 0x65 }, /* GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI -> 'e' */ + { 0xC8, 0x00 }, /* GREEK CAPITAL LETTER EPSILON WITH VARIA -> ... */ + { 0xCC, 0x45 }, /* GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI -> 'E' */ + { 0xD0, 0x00 }, /* GREEK SMALL LETTER IOTA WITH VRACHY -> ... */ + { 0xD3, 0x69 }, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA -> 'i' */ + { 0xD6, 0x69 }, /* GREEK SMALL LETTER IOTA WITH PERISPOMENI -> 'i' */ + { 0xD7, 0x69 }, /* GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI -> 'i' */ + { 0xD8, 0x00 }, /* GREEK CAPITAL LETTER IOTA WITH VRACHY -> ... */ + { 0xDB, 0x49 }, /* GREEK CAPITAL LETTER IOTA WITH OXIA -> 'I' */ + { 0xE0, 0x00 }, /* GREEK SMALL LETTER UPSILON WITH VRACHY -> ... */ + { 0xE3, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA -> 'u' */ + { 0xE4, 0x52 }, /* GREEK SMALL LETTER RHO WITH PSILI -> 'R' */ + { 0xE5, 0x52 }, /* GREEK SMALL LETTER RHO WITH DASIA -> 'R' */ + { 0xE6, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH PERISPOMENI -> 'u' */ + { 0xE7, 0x75 }, /* GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI -> 'u' */ + { 0xE8, 0x00 }, /* GREEK CAPITAL LETTER UPSILON WITH VRACHY -> ... */ + { 0xEB, 0x55 }, /* GREEK CAPITAL LETTER UPSILON WITH OXIA -> 'U' */ + { 0xEC, 0x52 }, /* GREEK CAPITAL LETTER RHO WITH DASIA -> 'R' */ + { 0xEF, 0x60 }, /* GREEK VARIA -> '`' */ + { 0xF2, 0x00 }, /* GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI -> ... */ + { 0xF4, 0x6F }, /* GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI -> 'o' */ + { 0xF6, 0x6F }, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI -> 'o' */ + { 0xF7, 0x6F }, /* GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI -> 'o' */ + { 0xF8, 0x00 }, /* GREEK CAPITAL LETTER OMICRON WITH VARIA -> ... */ + { 0xFC, 0x4F }, /* GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI -> 'O' */ + { 0xFD, 0x27 }, /* GREEK OXIA -> ''' */ + { 0xFE, 0x60 }, /* GREEK DASIA -> '`' */ + /* Entries for page 0x20 */ + { 0x00, 0x00 }, /* EN QUAD -> ... */ + { 0x0B, 0x20 }, /* ZERO WIDTH SPACE -> ' ' */ + { 0x10, 0x00 }, /* HYPHEN -> ... */ + { 0x15, 0x2D }, /* HORIZONTAL BAR -> '-' */ + { 0x17, 0x5F }, /* DOUBLE LOW LINE -> '_' */ + { 0x18, 0x27 }, /* LEFT SINGLE QUOTATION MARK -> ''' */ + { 0x19, 0x27 }, /* RIGHT SINGLE QUOTATION MARK -> ''' */ + { 0x1A, 0x2C }, /* SINGLE LOW-9 QUOTATION MARK -> ',' */ + { 0x1B, 0x27 }, /* SINGLE HIGH-REVERSED-9 QUOTATION MARK -> ''' */ + { 0x1C, 0x00 }, /* LEFT DOUBLE QUOTATION MARK -> ... */ + { 0x1F, 0x22 }, /* DOUBLE HIGH-REVERSED-9 QUOTATION MARK -> '"' */ + { 0x20, 0x2B }, /* DAGGER -> '+' */ + { 0x22, 0x2A }, /* BULLET -> '*' */ + { 0x23, 0x3E }, /* TRIANGULAR BULLET -> '>' */ + { 0x24, 0x2E }, /* ONE DOT LEADER -> '.' */ + { 0x26, 0x2E }, /* HORIZONTAL ELLIPSIS -> '.' */ + { 0x27, 0x2E }, /* HYPHENATION POINT -> '.' */ + { 0x2F, 0x20 }, /* NARROW NO-BREAK SPACE -> ' ' */ + { 0x32, 0x27 }, /* PRIME -> ''' */ + { 0x33, 0x22 }, /* DOUBLE PRIME -> '"' */ + { 0x35, 0x60 }, /* REVERSED PRIME -> '`' */ + { 0x38, 0x5E }, /* CARET -> '^' */ + { 0x39, 0x3C }, /* SINGLE LEFT-POINTING ANGLE QUOTATION MARK -> '<' */ + { 0x3A, 0x3E }, /* SINGLE RIGHT-POINTING ANGLE QUOTATION MARK -> '>' */ + { 0x3B, 0x2A }, /* REFERENCE MARK -> '*' */ + { 0x3C, 0x21 }, /* DOUBLE EXCLAMATION MARK -> '!' */ + { 0x3D, 0x3F }, /* INTERROBANG -> '?' */ + { 0x3E, 0x2D }, /* OVERLINE -> '-' */ + { 0x3F, 0x5F }, /* UNDERTIE -> '_' */ + { 0x40, 0x2D }, /* CHARACTER TIE -> '-' */ + { 0x41, 0x5E }, /* CARET INSERTION POINT -> '^' */ + { 0x42, 0x2A }, /* ASTERISM -> '*' */ + { 0x43, 0x2D }, /* HYPHEN BULLET -> '-' */ + { 0x44, 0x2F }, /* FRACTION SLASH -> '/' */ + { 0x47, 0x3F }, /* DOUBLE QUESTION MARK -> '?' */ + { 0x48, 0x3F }, /* QUESTION EXCLAMATION MARK -> '?' */ + { 0x49, 0x21 }, /* EXCLAMATION QUESTION MARK -> '!' */ + { 0x4A, 0x26 }, /* TIRONIAN SIGN ET -> '&' */ + { 0x4B, 0x50 }, /* REVERSED PILCROW SIGN -> 'P' */ + { 0x4C, 0x3C }, /* BLACK LEFTWARDS BULLET -> '<' */ + { 0x4D, 0x3E }, /* BLACK RIGHTWARDS BULLET -> '>' */ + { 0x4E, 0x2A }, /* LOW ASTERISK -> '*' */ + { 0x4F, 0x3B }, /* REVERSED SEMICOLON -> ';' */ + { 0x51, 0x2A }, /* TWO ASTERISKS ALIGNED VERTICALLY -> '*' */ + { 0x52, 0x2D }, /* COMMERCIAL MINUS SIGN -> '-' */ + { 0x53, 0x7E }, /* SWUNG DASH -> '~' */ + { 0x55, 0x2A }, /* FLOWER PUNCTUATION MARK -> '*' */ + { 0x5B, 0x3A }, /* FOUR DOT MARK -> ':' */ + { 0x5F, 0x20 }, /* MEDIUM MATHEMATICAL SPACE -> ' ' */ + { 0x70, 0x30 }, /* SUPERSCRIPT ZERO -> '0' */ + { 0x71, 0x69 }, /* SUPERSCRIPT LATIN SMALL LETTER I -> 'i' */ + { 0x74, 0x34 }, /* SUPERSCRIPT FOUR -> '4' */ + { 0x75, 0x35 }, /* SUPERSCRIPT FIVE -> '5' */ + { 0x76, 0x36 }, /* SUPERSCRIPT SIX -> '6' */ + { 0x77, 0x37 }, /* SUPERSCRIPT SEVEN -> '7' */ + { 0x78, 0x38 }, /* SUPERSCRIPT EIGHT -> '8' */ + { 0x79, 0x39 }, /* SUPERSCRIPT NINE -> '9' */ + { 0x7A, 0x2B }, /* SUPERSCRIPT PLUS SIGN -> '+' */ + { 0x7B, 0x2D }, /* SUPERSCRIPT MINUS -> '-' */ + { 0x7C, 0x3D }, /* SUPERSCRIPT EQUALS SIGN -> '=' */ + { 0x7D, 0x28 }, /* SUPERSCRIPT LEFT PARENTHESIS -> '(' */ + { 0x7E, 0x29 }, /* SUPERSCRIPT RIGHT PARENTHESIS -> ')' */ + { 0x7F, 0x6E }, /* SUPERSCRIPT LATIN SMALL LETTER N -> 'n' */ + { 0x80, 0x30 }, /* SUBSCRIPT ZERO -> '0' */ + { 0x81, 0x31 }, /* SUBSCRIPT ONE -> '1' */ + { 0x82, 0x32 }, /* SUBSCRIPT TWO -> '2' */ + { 0x83, 0x33 }, /* SUBSCRIPT THREE -> '3' */ + { 0x84, 0x34 }, /* SUBSCRIPT FOUR -> '4' */ + { 0x85, 0x35 }, /* SUBSCRIPT FIVE -> '5' */ + { 0x86, 0x36 }, /* SUBSCRIPT SIX -> '6' */ + { 0x87, 0x37 }, /* SUBSCRIPT SEVEN -> '7' */ + { 0x88, 0x38 }, /* SUBSCRIPT EIGHT -> '8' */ + { 0x89, 0x39 }, /* SUBSCRIPT NINE -> '9' */ + { 0x8A, 0x2B }, /* SUBSCRIPT PLUS SIGN -> '+' */ + { 0x8B, 0x2D }, /* SUBSCRIPT MINUS -> '-' */ + { 0x8C, 0x3D }, /* SUBSCRIPT EQUALS SIGN -> '=' */ + { 0x8D, 0x28 }, /* SUBSCRIPT LEFT PARENTHESIS -> '(' */ + { 0x8E, 0x29 }, /* SUBSCRIPT RIGHT PARENTHESIS -> ')' */ + { 0x90, 0x61 }, /* LATIN SUBSCRIPT SMALL LETTER A -> 'a' */ + { 0x91, 0x65 }, /* LATIN SUBSCRIPT SMALL LETTER E -> 'e' */ + { 0x92, 0x6F }, /* LATIN SUBSCRIPT SMALL LETTER O -> 'o' */ + { 0x93, 0x78 }, /* LATIN SUBSCRIPT SMALL LETTER X -> 'x' */ + { 0x95, 0x68 }, /* LATIN SUBSCRIPT SMALL LETTER H -> 'h' */ + { 0x96, 0x6B }, /* LATIN SUBSCRIPT SMALL LETTER K -> 'k' */ + { 0x97, 0x6C }, /* LATIN SUBSCRIPT SMALL LETTER L -> 'l' */ + { 0x98, 0x6D }, /* LATIN SUBSCRIPT SMALL LETTER M -> 'm' */ + { 0x99, 0x6E }, /* LATIN SUBSCRIPT SMALL LETTER N -> 'n' */ + { 0x9A, 0x70 }, /* LATIN SUBSCRIPT SMALL LETTER P -> 'p' */ + { 0x9B, 0x73 }, /* LATIN SUBSCRIPT SMALL LETTER S -> 's' */ + { 0x9C, 0x74 }, /* LATIN SUBSCRIPT SMALL LETTER T -> 't' */ + { 0xA4, 0x4C }, /* LIRA SIGN -> 'L' */ + { 0xA6, 0x4E }, /* NAIRA SIGN -> 'N' */ + { 0xA9, 0x57 }, /* WON SIGN -> 'W' */ + { 0xAB, 0x44 }, /* DONG SIGN -> 'D' */ + { 0xAC, 0x45 }, /* EURO SIGN -> 'E' */ + { 0xAD, 0x4B }, /* KIP SIGN -> 'K' */ + { 0xAE, 0x54 }, /* TUGRIK SIGN -> 'T' */ + { 0xB1, 0x50 }, /* PESO SIGN -> 'P' */ + { 0xB2, 0x47 }, /* GUARANI SIGN -> 'G' */ + { 0xB3, 0x41 }, /* AUSTRAL SIGN -> 'A' */ + { 0xB6, 0x4C }, /* LIVRE TOURNOIS SIGN -> 'L' */ + { 0xB8, 0x54 }, /* TENGE SIGN -> 'T' */ + { 0xBA, 0x4C }, /* TURKISH LIRA SIGN -> 'L' */ + { 0xBB, 0x4D }, /* NORDIC MARK SIGN -> 'M' */ + { 0xBC, 0x6D }, /* MANAT SIGN -> 'm' */ + { 0xBD, 0x52 }, /* RUBLE SIGN -> 'R' */ + { 0xBE, 0x6C }, /* LARI SIGN -> 'l' */ + /* Entries for page 0x21 */ + { 0x02, 0x43 }, /* DOUBLE-STRUCK CAPITAL C -> 'C' */ + { 0x03, 0x43 }, /* DEGREE CELSIUS -> 'C' */ + { 0x09, 0x46 }, /* DEGREE FAHRENHEIT -> 'F' */ + { 0x0A, 0x67 }, /* SCRIPT SMALL G -> 'g' */ + { 0x0B, 0x00 }, /* SCRIPT CAPITAL H -> ... */ + { 0x0D, 0x48 }, /* DOUBLE-STRUCK CAPITAL H -> 'H' */ + { 0x0E, 0x68 }, /* PLANCK CONSTANT -> 'h' */ + { 0x10, 0x49 }, /* SCRIPT CAPITAL I -> 'I' */ + { 0x11, 0x49 }, /* BLACK-LETTER CAPITAL I -> 'I' */ + { 0x12, 0x4C }, /* SCRIPT CAPITAL L -> 'L' */ + { 0x13, 0x6C }, /* SCRIPT SMALL L -> 'l' */ + { 0x15, 0x4E }, /* DOUBLE-STRUCK CAPITAL N -> 'N' */ + { 0x19, 0x50 }, /* DOUBLE-STRUCK CAPITAL P -> 'P' */ + { 0x1A, 0x51 }, /* DOUBLE-STRUCK CAPITAL Q -> 'Q' */ + { 0x1B, 0x00 }, /* SCRIPT CAPITAL R -> ... */ + { 0x1D, 0x52 }, /* DOUBLE-STRUCK CAPITAL R -> 'R' */ + { 0x22, 0x54 }, /* TRADE MARK SIGN -> 'T' */ + { 0x24, 0x5A }, /* DOUBLE-STRUCK CAPITAL Z -> 'Z' */ + { 0x28, 0x5A }, /* BLACK-LETTER CAPITAL Z -> 'Z' */ + { 0x2A, 0x4B }, /* KELVIN SIGN -> 'K' */ + { 0x2B, 0x41 }, /* ANGSTROM SIGN -> 'A' */ + { 0x2C, 0x42 }, /* SCRIPT CAPITAL B -> 'B' */ + { 0x2D, 0x43 }, /* BLACK-LETTER CAPITAL C -> 'C' */ + { 0x2E, 0x65 }, /* ESTIMATED SYMBOL -> 'e' */ + { 0x2F, 0x65 }, /* SCRIPT SMALL E -> 'e' */ + { 0x30, 0x45 }, /* SCRIPT CAPITAL E -> 'E' */ + { 0x31, 0x46 }, /* SCRIPT CAPITAL F -> 'F' */ + { 0x32, 0x46 }, /* TURNED CAPITAL F -> 'F' */ + { 0x33, 0x4D }, /* SCRIPT CAPITAL M -> 'M' */ + { 0x34, 0x6F }, /* SCRIPT SMALL O -> 'o' */ + { 0x39, 0x69 }, /* INFORMATION SOURCE -> 'i' */ + { 0x45, 0x44 }, /* DOUBLE-STRUCK ITALIC CAPITAL D -> 'D' */ + { 0x46, 0x64 }, /* DOUBLE-STRUCK ITALIC SMALL D -> 'd' */ + { 0x47, 0x65 }, /* DOUBLE-STRUCK ITALIC SMALL E -> 'e' */ + { 0x48, 0x69 }, /* DOUBLE-STRUCK ITALIC SMALL I -> 'i' */ + { 0x49, 0x6A }, /* DOUBLE-STRUCK ITALIC SMALL J -> 'j' */ + { 0x4E, 0x46 }, /* TURNED SMALL F -> 'F' */ + { 0x60, 0x49 }, /* ROMAN NUMERAL ONE -> 'I' */ + { 0x64, 0x56 }, /* ROMAN NUMERAL FIVE -> 'V' */ + { 0x69, 0x58 }, /* ROMAN NUMERAL TEN -> 'X' */ + { 0x6C, 0x4C }, /* ROMAN NUMERAL FIFTY -> 'L' */ + { 0x6D, 0x43 }, /* ROMAN NUMERAL ONE HUNDRED -> 'C' */ + { 0x6E, 0x44 }, /* ROMAN NUMERAL FIVE HUNDRED -> 'D' */ + { 0x6F, 0x4D }, /* ROMAN NUMERAL ONE THOUSAND -> 'M' */ + { 0x70, 0x69 }, /* SMALL ROMAN NUMERAL ONE -> 'i' */ + { 0x74, 0x76 }, /* SMALL ROMAN NUMERAL FIVE -> 'v' */ + { 0x79, 0x78 }, /* SMALL ROMAN NUMERAL TEN -> 'x' */ + { 0x7C, 0x6C }, /* SMALL ROMAN NUMERAL FIFTY -> 'l' */ + { 0x7D, 0x63 }, /* SMALL ROMAN NUMERAL ONE HUNDRED -> 'c' */ + { 0x7E, 0x64 }, /* SMALL ROMAN NUMERAL FIVE HUNDRED -> 'd' */ + { 0x7F, 0x6D }, /* SMALL ROMAN NUMERAL ONE THOUSAND -> 'm' */ + { 0x83, 0x29 }, /* ROMAN NUMERAL REVERSED ONE HUNDRED -> ')' */ + { 0x90, 0x3C }, /* LEFTWARDS ARROW -> '<' */ + { 0x91, 0x5E }, /* UPWARDS ARROW -> '^' */ + { 0x92, 0x3E }, /* RIGHTWARDS ARROW -> '>' */ + { 0x93, 0x76 }, /* DOWNWARDS ARROW -> 'v' */ + { 0x94, 0x2D }, /* LEFT RIGHT ARROW -> '-' */ + { 0x95, 0x7C }, /* UP DOWN ARROW -> '|' */ + { 0x96, 0x5C }, /* NORTH WEST ARROW -> '\' */ + { 0x97, 0x2F }, /* NORTH EAST ARROW -> '/' */ + { 0x98, 0x5C }, /* SOUTH EAST ARROW -> '\' */ + { 0x99, 0x2F }, /* SOUTH WEST ARROW -> '/' */ + { 0x9A, 0x21 }, /* LEFTWARDS ARROW WITH STROKE -> '!' */ + { 0x9B, 0x21 }, /* RIGHTWARDS ARROW WITH STROKE -> '!' */ + { 0x9C, 0x7E }, /* LEFTWARDS WAVE ARROW -> '~' */ + { 0x9D, 0x7E }, /* RIGHTWARDS WAVE ARROW -> '~' */ + { 0x9E, 0x2D }, /* LEFTWARDS TWO HEADED ARROW -> '-' */ + { 0x9F, 0x7C }, /* UPWARDS TWO HEADED ARROW -> '|' */ + { 0xA0, 0x2D }, /* RIGHTWARDS TWO HEADED ARROW -> '-' */ + { 0xA1, 0x7C }, /* DOWNWARDS TWO HEADED ARROW -> '|' */ + { 0xA2, 0x00 }, /* LEFTWARDS ARROW WITH TAIL -> ... */ + { 0xA4, 0x2D }, /* LEFTWARDS ARROW FROM BAR -> '-' */ + { 0xA5, 0x7C }, /* UPWARDS ARROW FROM BAR -> '|' */ + { 0xA6, 0x2D }, /* RIGHTWARDS ARROW FROM BAR -> '-' */ + { 0xA7, 0x7C }, /* DOWNWARDS ARROW FROM BAR -> '|' */ + { 0xA8, 0x7C }, /* UP DOWN ARROW WITH BASE -> '|' */ + { 0xA9, 0x00 }, /* LEFTWARDS ARROW WITH HOOK -> ... */ + { 0xAD, 0x2D }, /* LEFT RIGHT WAVE ARROW -> '-' */ + { 0xAE, 0x21 }, /* LEFT RIGHT ARROW WITH STROKE -> '!' */ + { 0xAF, 0x00 }, /* DOWNWARDS ZIGZAG ARROW -> ... */ + { 0xB5, 0x7C }, /* DOWNWARDS ARROW WITH CORNER LEFTWARDS -> '|' */ + { 0xB6, 0x5E }, /* ANTICLOCKWISE TOP SEMICIRCLE ARROW -> '^' */ + { 0xB7, 0x56 }, /* CLOCKWISE TOP SEMICIRCLE ARROW -> 'V' */ + { 0xB8, 0x5C }, /* NORTH WEST ARROW TO LONG BAR -> '\' */ + { 0xB9, 0x3D }, /* LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR -> '=' */ + { 0xBA, 0x56 }, /* ANTICLOCKWISE OPEN CIRCLE ARROW -> 'V' */ + { 0xBB, 0x5E }, /* CLOCKWISE OPEN CIRCLE ARROW -> '^' */ + { 0xBC, 0x2D }, /* LEFTWARDS HARPOON WITH BARB UPWARDS -> '-' */ + { 0xBD, 0x2D }, /* LEFTWARDS HARPOON WITH BARB DOWNWARDS -> '-' */ + { 0xBE, 0x7C }, /* UPWARDS HARPOON WITH BARB RIGHTWARDS -> '|' */ + { 0xBF, 0x7C }, /* UPWARDS HARPOON WITH BARB LEFTWARDS -> '|' */ + { 0xC0, 0x2D }, /* RIGHTWARDS HARPOON WITH BARB UPWARDS -> '-' */ + { 0xC1, 0x2D }, /* RIGHTWARDS HARPOON WITH BARB DOWNWARDS -> '-' */ + { 0xC2, 0x7C }, /* DOWNWARDS HARPOON WITH BARB RIGHTWARDS -> '|' */ + { 0xC3, 0x7C }, /* DOWNWARDS HARPOON WITH BARB LEFTWARDS -> '|' */ + { 0xC4, 0x3D }, /* RIGHTWARDS ARROW OVER LEFTWARDS ARROW -> '=' */ + { 0xC5, 0x7C }, /* UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW -> '|' */ + { 0xC6, 0x3D }, /* LEFTWARDS ARROW OVER RIGHTWARDS ARROW -> '=' */ + { 0xC7, 0x3D }, /* LEFTWARDS PAIRED ARROWS -> '=' */ + { 0xC8, 0x7C }, /* UPWARDS PAIRED ARROWS -> '|' */ + { 0xC9, 0x3D }, /* RIGHTWARDS PAIRED ARROWS -> '=' */ + { 0xCA, 0x7C }, /* DOWNWARDS PAIRED ARROWS -> '|' */ + { 0xCB, 0x3D }, /* LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON -> '=' */ + { 0xCC, 0x3D }, /* RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON -> '=' */ + { 0xCD, 0x00 }, /* LEFTWARDS DOUBLE ARROW WITH STROKE -> ... */ + { 0xCF, 0x21 }, /* RIGHTWARDS DOUBLE ARROW WITH STROKE -> '!' */ + { 0xD0, 0x3C }, /* LEFTWARDS DOUBLE ARROW -> '<' */ + { 0xD1, 0x5E }, /* UPWARDS DOUBLE ARROW -> '^' */ + { 0xD2, 0x3E }, /* RIGHTWARDS DOUBLE ARROW -> '>' */ + { 0xD3, 0x76 }, /* DOWNWARDS DOUBLE ARROW -> 'v' */ + { 0xD4, 0x3D }, /* LEFT RIGHT DOUBLE ARROW -> '=' */ + { 0xD5, 0x7C }, /* UP DOWN DOUBLE ARROW -> '|' */ + { 0xD6, 0x5C }, /* NORTH WEST DOUBLE ARROW -> '\' */ + { 0xD7, 0x2F }, /* NORTH EAST DOUBLE ARROW -> '/' */ + { 0xD8, 0x5C }, /* SOUTH EAST DOUBLE ARROW -> '\' */ + { 0xD9, 0x2F }, /* SOUTH WEST DOUBLE ARROW -> '/' */ + { 0xDA, 0x3D }, /* LEFTWARDS TRIPLE ARROW -> '=' */ + { 0xDB, 0x3D }, /* RIGHTWARDS TRIPLE ARROW -> '=' */ + { 0xDC, 0x7E }, /* LEFTWARDS SQUIGGLE ARROW -> '~' */ + { 0xDD, 0x7E }, /* RIGHTWARDS SQUIGGLE ARROW -> '~' */ + { 0xDE, 0x7C }, /* UPWARDS ARROW WITH DOUBLE STROKE -> '|' */ + { 0xDF, 0x7C }, /* DOWNWARDS ARROW WITH DOUBLE STROKE -> '|' */ + { 0xE0, 0x2D }, /* LEFTWARDS DASHED ARROW -> '-' */ + { 0xE1, 0x7C }, /* UPWARDS DASHED ARROW -> '|' */ + { 0xE2, 0x2D }, /* RIGHTWARDS DASHED ARROW -> '-' */ + { 0xE3, 0x7C }, /* DOWNWARDS DASHED ARROW -> '|' */ + { 0xE4, 0x00 }, /* LEFTWARDS ARROW TO BAR -> ... */ + { 0xE6, 0x2D }, /* LEFTWARDS WHITE ARROW -> '-' */ + { 0xE7, 0x7C }, /* UPWARDS WHITE ARROW -> '|' */ + { 0xE8, 0x2D }, /* RIGHTWARDS WHITE ARROW -> '-' */ + { 0xE9, 0x00 }, /* DOWNWARDS WHITE ARROW -> ... */ + { 0xEF, 0x7C }, /* UPWARDS WHITE DOUBLE ARROW ON PEDESTAL -> '|' */ + { 0xF0, 0x2D }, /* RIGHTWARDS WHITE ARROW FROM WALL -> '-' */ + { 0xF1, 0x5C }, /* NORTH WEST ARROW TO CORNER -> '\' */ + { 0xF2, 0x5C }, /* SOUTH EAST ARROW TO CORNER -> '\' */ + { 0xF3, 0x7C }, /* UP DOWN WHITE ARROW -> '|' */ + /* Entries for page 0x22 */ + { 0x04, 0x21 }, /* THERE DOES NOT EXIST -> '!' */ + { 0x09, 0x21 }, /* NOT AN ELEMENT OF -> '!' */ + { 0x0C, 0x21 }, /* DOES NOT CONTAIN AS MEMBER -> '!' */ + { 0x12, 0x2D }, /* MINUS SIGN -> '-' */ + { 0x15, 0x2F }, /* DIVISION SLASH -> '/' */ + { 0x16, 0x5C }, /* SET MINUS -> '\' */ + { 0x17, 0x2A }, /* ASTERISK OPERATOR -> '*' */ + { 0x18, 0x6F }, /* RING OPERATOR -> 'o' */ + { 0x19, 0x2E }, /* BULLET OPERATOR -> '.' */ + { 0x23, 0x7C }, /* DIVIDES -> '|' */ + { 0x24, 0x21 }, /* DOES NOT DIVIDE -> '!' */ + { 0x26, 0x21 }, /* NOT PARALLEL TO -> '!' */ + { 0x36, 0x3A }, /* RATIO -> ':' */ + { 0x3C, 0x7E }, /* TILDE OPERATOR -> '~' */ + { 0x41, 0x23 }, /* NOT TILDE -> '#' */ + { 0x44, 0x23 }, /* NOT ASYMPTOTICALLY EQUAL TO -> '#' */ + { 0x49, 0x23 }, /* NOT ALMOST EQUAL TO -> '#' */ + { 0x60, 0x23 }, /* NOT EQUAL TO -> '#' */ + { 0x62, 0x23 }, /* NOT IDENTICAL TO -> '#' */ + { 0x64, 0x3C }, /* LESS-THAN OR EQUAL TO -> '<' */ + { 0x65, 0x3E }, /* GREATER-THAN OR EQUAL TO -> '>' */ + { 0x68, 0x23 }, /* LESS-THAN BUT NOT EQUAL TO -> '#' */ + { 0x69, 0x23 }, /* GREATER-THAN BUT NOT EQUAL TO -> '#' */ + { 0x6D, 0x23 }, /* NOT EQUIVALENT TO -> '#' */ + { 0x6E, 0x21 }, /* NOT LESS-THAN -> '!' */ + { 0x6F, 0x21 }, /* NOT GREATER-THAN -> '!' */ + { 0x80, 0x21 }, /* DOES NOT PRECEDE -> '!' */ + { 0x81, 0x21 }, /* DOES NOT SUCCEED -> '!' */ + { 0x84, 0x21 }, /* NOT A SUBSET OF -> '!' */ + { 0x85, 0x21 }, /* NOT A SUPERSET OF -> '!' */ + { 0x8A, 0x23 }, /* SUBSET OF WITH NOT EQUAL TO -> '#' */ + { 0x8B, 0x23 }, /* SUPERSET OF WITH NOT EQUAL TO -> '#' */ + { 0x9B, 0x2A }, /* CIRCLED ASTERISK OPERATOR -> '*' */ + { 0xC6, 0x2A }, /* STAR OPERATOR -> '*' */ + /* Entries for page 0x23 */ + { 0x03, 0x5E }, /* UP ARROWHEAD -> '^' */ + { 0x29, 0x3C }, /* LEFT-POINTING ANGLE BRACKET -> '<' */ + { 0x5F, 0x2A }, /* APL FUNCTIONAL SYMBOL CIRCLE STAR -> '*' */ + { 0x63, 0x2A }, /* APL FUNCTIONAL SYMBOL STAR DIAERESIS -> '*' */ + /* Entries for page 0x24 */ + { 0x60, 0x31 }, /* CIRCLED DIGIT ONE -> '1' */ + { 0x61, 0x32 }, /* CIRCLED DIGIT TWO -> '2' */ + { 0x62, 0x33 }, /* CIRCLED DIGIT THREE -> '3' */ + { 0x63, 0x34 }, /* CIRCLED DIGIT FOUR -> '4' */ + { 0x64, 0x35 }, /* CIRCLED DIGIT FIVE -> '5' */ + { 0x65, 0x36 }, /* CIRCLED DIGIT SIX -> '6' */ + { 0x66, 0x37 }, /* CIRCLED DIGIT SEVEN -> '7' */ + { 0x67, 0x38 }, /* CIRCLED DIGIT EIGHT -> '8' */ + { 0x68, 0x39 }, /* CIRCLED DIGIT NINE -> '9' */ + { 0xB6, 0x41 }, /* CIRCLED LATIN CAPITAL LETTER A -> 'A' */ + { 0xB7, 0x42 }, /* CIRCLED LATIN CAPITAL LETTER B -> 'B' */ + { 0xB8, 0x43 }, /* CIRCLED LATIN CAPITAL LETTER C -> 'C' */ + { 0xB9, 0x44 }, /* CIRCLED LATIN CAPITAL LETTER D -> 'D' */ + { 0xBA, 0x45 }, /* CIRCLED LATIN CAPITAL LETTER E -> 'E' */ + { 0xBB, 0x46 }, /* CIRCLED LATIN CAPITAL LETTER F -> 'F' */ + { 0xBC, 0x47 }, /* CIRCLED LATIN CAPITAL LETTER G -> 'G' */ + { 0xBD, 0x48 }, /* CIRCLED LATIN CAPITAL LETTER H -> 'H' */ + { 0xBE, 0x49 }, /* CIRCLED LATIN CAPITAL LETTER I -> 'I' */ + { 0xBF, 0x4A }, /* CIRCLED LATIN CAPITAL LETTER J -> 'J' */ + { 0xC0, 0x4B }, /* CIRCLED LATIN CAPITAL LETTER K -> 'K' */ + { 0xC1, 0x4C }, /* CIRCLED LATIN CAPITAL LETTER L -> 'L' */ + { 0xC2, 0x4D }, /* CIRCLED LATIN CAPITAL LETTER M -> 'M' */ + { 0xC3, 0x4E }, /* CIRCLED LATIN CAPITAL LETTER N -> 'N' */ + { 0xC4, 0x4F }, /* CIRCLED LATIN CAPITAL LETTER O -> 'O' */ + { 0xC5, 0x50 }, /* CIRCLED LATIN CAPITAL LETTER P -> 'P' */ + { 0xC6, 0x51 }, /* CIRCLED LATIN CAPITAL LETTER Q -> 'Q' */ + { 0xC7, 0x52 }, /* CIRCLED LATIN CAPITAL LETTER R -> 'R' */ + { 0xC8, 0x53 }, /* CIRCLED LATIN CAPITAL LETTER S -> 'S' */ + { 0xC9, 0x54 }, /* CIRCLED LATIN CAPITAL LETTER T -> 'T' */ + { 0xCA, 0x55 }, /* CIRCLED LATIN CAPITAL LETTER U -> 'U' */ + { 0xCB, 0x56 }, /* CIRCLED LATIN CAPITAL LETTER V -> 'V' */ + { 0xCC, 0x57 }, /* CIRCLED LATIN CAPITAL LETTER W -> 'W' */ + { 0xCD, 0x58 }, /* CIRCLED LATIN CAPITAL LETTER X -> 'X' */ + { 0xCE, 0x59 }, /* CIRCLED LATIN CAPITAL LETTER Y -> 'Y' */ + { 0xCF, 0x5A }, /* CIRCLED LATIN CAPITAL LETTER Z -> 'Z' */ + { 0xD0, 0x61 }, /* CIRCLED LATIN SMALL LETTER A -> 'a' */ + { 0xD1, 0x62 }, /* CIRCLED LATIN SMALL LETTER B -> 'b' */ + { 0xD2, 0x63 }, /* CIRCLED LATIN SMALL LETTER C -> 'c' */ + { 0xD3, 0x64 }, /* CIRCLED LATIN SMALL LETTER D -> 'd' */ + { 0xD4, 0x65 }, /* CIRCLED LATIN SMALL LETTER E -> 'e' */ + { 0xD5, 0x66 }, /* CIRCLED LATIN SMALL LETTER F -> 'f' */ + { 0xD6, 0x67 }, /* CIRCLED LATIN SMALL LETTER G -> 'g' */ + { 0xD7, 0x68 }, /* CIRCLED LATIN SMALL LETTER H -> 'h' */ + { 0xD8, 0x69 }, /* CIRCLED LATIN SMALL LETTER I -> 'i' */ + { 0xD9, 0x6A }, /* CIRCLED LATIN SMALL LETTER J -> 'j' */ + { 0xDA, 0x6B }, /* CIRCLED LATIN SMALL LETTER K -> 'k' */ + { 0xDB, 0x6C }, /* CIRCLED LATIN SMALL LETTER L -> 'l' */ + { 0xDC, 0x6D }, /* CIRCLED LATIN SMALL LETTER M -> 'm' */ + { 0xDD, 0x6E }, /* CIRCLED LATIN SMALL LETTER N -> 'n' */ + { 0xDE, 0x6F }, /* CIRCLED LATIN SMALL LETTER O -> 'o' */ + { 0xDF, 0x70 }, /* CIRCLED LATIN SMALL LETTER P -> 'p' */ + { 0xE0, 0x71 }, /* CIRCLED LATIN SMALL LETTER Q -> 'q' */ + { 0xE1, 0x72 }, /* CIRCLED LATIN SMALL LETTER R -> 'r' */ + { 0xE2, 0x73 }, /* CIRCLED LATIN SMALL LETTER S -> 's' */ + { 0xE3, 0x74 }, /* CIRCLED LATIN SMALL LETTER T -> 't' */ + { 0xE4, 0x75 }, /* CIRCLED LATIN SMALL LETTER U -> 'u' */ + { 0xE5, 0x76 }, /* CIRCLED LATIN SMALL LETTER V -> 'v' */ + { 0xE6, 0x77 }, /* CIRCLED LATIN SMALL LETTER W -> 'w' */ + { 0xE7, 0x78 }, /* CIRCLED LATIN SMALL LETTER X -> 'x' */ + { 0xE8, 0x79 }, /* CIRCLED LATIN SMALL LETTER Y -> 'y' */ + { 0xE9, 0x7A }, /* CIRCLED LATIN SMALL LETTER Z -> 'z' */ + { 0xEA, 0x30 }, /* CIRCLED DIGIT ZERO -> '0' */ + { 0xF5, 0x31 }, /* DOUBLE CIRCLED DIGIT ONE -> '1' */ + { 0xF6, 0x32 }, /* DOUBLE CIRCLED DIGIT TWO -> '2' */ + { 0xF7, 0x33 }, /* DOUBLE CIRCLED DIGIT THREE -> '3' */ + { 0xF8, 0x34 }, /* DOUBLE CIRCLED DIGIT FOUR -> '4' */ + { 0xF9, 0x35 }, /* DOUBLE CIRCLED DIGIT FIVE -> '5' */ + { 0xFA, 0x36 }, /* DOUBLE CIRCLED DIGIT SIX -> '6' */ + { 0xFB, 0x37 }, /* DOUBLE CIRCLED DIGIT SEVEN -> '7' */ + { 0xFC, 0x38 }, /* DOUBLE CIRCLED DIGIT EIGHT -> '8' */ + { 0xFD, 0x39 }, /* DOUBLE CIRCLED DIGIT NINE -> '9' */ + { 0xFF, 0x30 }, /* NEGATIVE CIRCLED DIGIT ZERO -> '0' */ + /* Entries for page 0x25 */ + { 0x00, 0x2D }, /* BOX DRAWINGS LIGHT HORIZONTAL -> '-' */ + { 0x01, 0x2D }, /* BOX DRAWINGS HEAVY HORIZONTAL -> '-' */ + { 0x02, 0x7C }, /* BOX DRAWINGS LIGHT VERTICAL -> '|' */ + { 0x03, 0x7C }, /* BOX DRAWINGS HEAVY VERTICAL -> '|' */ + { 0x04, 0x2D }, /* BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL -> '-' */ + { 0x05, 0x2D }, /* BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL -> '-' */ + { 0x06, 0x7C }, /* BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL -> '|' */ + { 0x07, 0x7C }, /* BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL -> '|' */ + { 0x08, 0x2D }, /* BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL -> '-' */ + { 0x09, 0x2D }, /* BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL -> '-' */ + { 0x0A, 0x7C }, /* BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL -> '|' */ + { 0x0B, 0x7C }, /* BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL -> '|' */ + { 0x0C, 0x00 }, /* BOX DRAWINGS LIGHT DOWN AND RIGHT -> ... */ + { 0x4B, 0x2B }, /* BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL -> '+' */ + { 0x4C, 0x2D }, /* BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL -> '-' */ + { 0x4D, 0x2D }, /* BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL -> '-' */ + { 0x4E, 0x7C }, /* BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL -> '|' */ + { 0x4F, 0x7C }, /* BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL -> '|' */ + { 0x50, 0x2D }, /* BOX DRAWINGS DOUBLE HORIZONTAL -> '-' */ + { 0x51, 0x7C }, /* BOX DRAWINGS DOUBLE VERTICAL -> '|' */ + { 0x52, 0x00 }, /* BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE -> ... */ + { 0x70, 0x2B }, /* BOX DRAWINGS LIGHT ARC UP AND RIGHT -> '+' */ + { 0x71, 0x2F }, /* BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT -> '/' */ + { 0x72, 0x5C }, /* BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT -> '\' */ + { 0x73, 0x58 }, /* BOX DRAWINGS LIGHT DIAGONAL CROSS -> 'X' */ + { 0x74, 0x2D }, /* BOX DRAWINGS LIGHT LEFT -> '-' */ + { 0x75, 0x7C }, /* BOX DRAWINGS LIGHT UP -> '|' */ + { 0x76, 0x2D }, /* BOX DRAWINGS LIGHT RIGHT -> '-' */ + { 0x77, 0x7C }, /* BOX DRAWINGS LIGHT DOWN -> '|' */ + { 0x78, 0x2D }, /* BOX DRAWINGS HEAVY LEFT -> '-' */ + { 0x79, 0x7C }, /* BOX DRAWINGS HEAVY UP -> '|' */ + { 0x7A, 0x2D }, /* BOX DRAWINGS HEAVY RIGHT -> '-' */ + { 0x7B, 0x7C }, /* BOX DRAWINGS HEAVY DOWN -> '|' */ + { 0x7C, 0x2D }, /* BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT -> '-' */ + { 0x7D, 0x7C }, /* BOX DRAWINGS LIGHT UP AND HEAVY DOWN -> '|' */ + { 0x7E, 0x2D }, /* BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT -> '-' */ + { 0x7F, 0x7C }, /* BOX DRAWINGS HEAVY UP AND LIGHT DOWN -> '|' */ + { 0x80, 0x00 }, /* UPPER HALF BLOCK -> ... */ + { 0x93, 0x23 }, /* DARK SHADE -> '#' */ + { 0x94, 0x2D }, /* UPPER ONE EIGHTH BLOCK -> '-' */ + { 0x95, 0x7C }, /* RIGHT ONE EIGHTH BLOCK -> '|' */ + { 0x96, 0x00 }, /* QUADRANT LOWER LEFT -> ... */ + { 0xB1, 0x23 }, /* WHITE PARALLELOGRAM -> '#' */ + { 0xB2, 0x00 }, /* BLACK UP-POINTING TRIANGLE -> ... */ + { 0xB5, 0x5E }, /* WHITE UP-POINTING SMALL TRIANGLE -> '^' */ + { 0xB6, 0x00 }, /* BLACK RIGHT-POINTING TRIANGLE -> ... */ + { 0xBB, 0x3E }, /* WHITE RIGHT-POINTING POINTER -> '>' */ + { 0xBC, 0x00 }, /* BLACK DOWN-POINTING TRIANGLE -> ... */ + { 0xBF, 0x56 }, /* WHITE DOWN-POINTING SMALL TRIANGLE -> 'V' */ + { 0xC0, 0x00 }, /* BLACK LEFT-POINTING TRIANGLE -> ... */ + { 0xC5, 0x3C }, /* WHITE LEFT-POINTING POINTER -> '<' */ + { 0xC6, 0x00 }, /* BLACK DIAMOND -> ... */ + { 0xE6, 0x2A }, /* WHITE BULLET -> '*' */ + { 0xE7, 0x00 }, /* SQUARE WITH LEFT HALF BLACK -> ... */ + { 0xEB, 0x23 }, /* WHITE SQUARE WITH VERTICAL BISECTING LINE -> '#' */ + { 0xEC, 0x00 }, /* WHITE UP-POINTING TRIANGLE WITH DOT -> ... */ + { 0xEE, 0x5E }, /* UP-POINTING TRIANGLE WITH RIGHT HALF BLACK -> '^' */ + { 0xEF, 0x4F }, /* LARGE CIRCLE -> 'O' */ + { 0xF0, 0x00 }, /* WHITE SQUARE WITH UPPER LEFT QUADRANT -> ... */ + { 0xF7, 0x23 }, /* WHITE CIRCLE WITH UPPER RIGHT QUADRANT -> '#' */ + /* Entries for page 0x26 */ + { 0x05, 0x2A }, /* BLACK STAR -> '*' */ + { 0x06, 0x2A }, /* WHITE STAR -> '*' */ + { 0x2A, 0x2A }, /* STAR AND CRESCENT -> '*' */ + { 0x6F, 0x23 }, /* MUSIC SHARP SIGN -> '#' */ + { 0x98, 0x2A }, /* FLOWER -> '*' */ + { 0x9D, 0x2A }, /* OUTLINED WHITE STAR -> '*' */ + /* Entries for page 0x27 */ + { 0x13, 0x76 }, /* CHECK MARK -> 'v' */ + { 0x14, 0x56 }, /* HEAVY CHECK MARK -> 'V' */ + { 0x15, 0x78 }, /* MULTIPLICATION X -> 'x' */ + { 0x16, 0x58 }, /* HEAVY MULTIPLICATION X -> 'X' */ + { 0x17, 0x78 }, /* BALLOT X -> 'x' */ + { 0x18, 0x58 }, /* HEAVY BALLOT X -> 'X' */ + { 0x21, 0x00 }, /* STAR OF DAVID -> ... */ + { 0x46, 0x2A }, /* HEAVY CHEVRON SNOWFLAKE -> '*' */ + { 0x49, 0x00 }, /* BALLOON-SPOKED ASTERISK -> ... */ + { 0x4B, 0x2A }, /* HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK -> '*' */ + { 0x58, 0x7C }, /* LIGHT VERTICAL BAR -> '|' */ + { 0x5C, 0x27 }, /* HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT -> ''' */ + { 0x5D, 0x22 }, /* HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT -> '"' */ + { 0x5E, 0x22 }, /* HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT -> '"' */ + { 0x5F, 0x2C }, /* HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT -> ',' */ + { 0x62, 0x21 }, /* HEAVY EXCLAMATION MARK ORNAMENT -> '!' */ + { 0xE6, 0x5B }, /* MATHEMATICAL LEFT WHITE SQUARE BRACKET -> '[' */ + { 0xE8, 0x3C }, /* MATHEMATICAL LEFT ANGLE BRACKET -> '<' */ + /* Entries for page 0x28 */ + { 0x00, 0x20 }, /* BRAILLE PATTERN BLANK -> ' ' */ + { 0x01, 0x61 }, /* BRAILLE PATTERN DOTS-1 -> 'a' */ + { 0x02, 0x31 }, /* BRAILLE PATTERN DOTS-2 -> '1' */ + { 0x03, 0x62 }, /* BRAILLE PATTERN DOTS-12 -> 'b' */ + { 0x04, 0x27 }, /* BRAILLE PATTERN DOTS-3 -> ''' */ + { 0x05, 0x6B }, /* BRAILLE PATTERN DOTS-13 -> 'k' */ + { 0x06, 0x32 }, /* BRAILLE PATTERN DOTS-23 -> '2' */ + { 0x07, 0x6C }, /* BRAILLE PATTERN DOTS-123 -> 'l' */ + { 0x08, 0x40 }, /* BRAILLE PATTERN DOTS-4 -> '@' */ + { 0x09, 0x63 }, /* BRAILLE PATTERN DOTS-14 -> 'c' */ + { 0x0A, 0x69 }, /* BRAILLE PATTERN DOTS-24 -> 'i' */ + { 0x0B, 0x66 }, /* BRAILLE PATTERN DOTS-124 -> 'f' */ + { 0x0C, 0x2F }, /* BRAILLE PATTERN DOTS-34 -> '/' */ + { 0x0D, 0x6D }, /* BRAILLE PATTERN DOTS-134 -> 'm' */ + { 0x0E, 0x73 }, /* BRAILLE PATTERN DOTS-234 -> 's' */ + { 0x0F, 0x70 }, /* BRAILLE PATTERN DOTS-1234 -> 'p' */ + { 0x10, 0x22 }, /* BRAILLE PATTERN DOTS-5 -> '"' */ + { 0x11, 0x65 }, /* BRAILLE PATTERN DOTS-15 -> 'e' */ + { 0x12, 0x33 }, /* BRAILLE PATTERN DOTS-25 -> '3' */ + { 0x13, 0x68 }, /* BRAILLE PATTERN DOTS-125 -> 'h' */ + { 0x14, 0x39 }, /* BRAILLE PATTERN DOTS-35 -> '9' */ + { 0x15, 0x6F }, /* BRAILLE PATTERN DOTS-135 -> 'o' */ + { 0x16, 0x36 }, /* BRAILLE PATTERN DOTS-235 -> '6' */ + { 0x17, 0x72 }, /* BRAILLE PATTERN DOTS-1235 -> 'r' */ + { 0x18, 0x5E }, /* BRAILLE PATTERN DOTS-45 -> '^' */ + { 0x19, 0x64 }, /* BRAILLE PATTERN DOTS-145 -> 'd' */ + { 0x1A, 0x6A }, /* BRAILLE PATTERN DOTS-245 -> 'j' */ + { 0x1B, 0x67 }, /* BRAILLE PATTERN DOTS-1245 -> 'g' */ + { 0x1C, 0x3E }, /* BRAILLE PATTERN DOTS-345 -> '>' */ + { 0x1D, 0x6E }, /* BRAILLE PATTERN DOTS-1345 -> 'n' */ + { 0x1E, 0x74 }, /* BRAILLE PATTERN DOTS-2345 -> 't' */ + { 0x1F, 0x71 }, /* BRAILLE PATTERN DOTS-12345 -> 'q' */ + { 0x20, 0x2C }, /* BRAILLE PATTERN DOTS-6 -> ',' */ + { 0x21, 0x2A }, /* BRAILLE PATTERN DOTS-16 -> '*' */ + { 0x22, 0x35 }, /* BRAILLE PATTERN DOTS-26 -> '5' */ + { 0x23, 0x3C }, /* BRAILLE PATTERN DOTS-126 -> '<' */ + { 0x24, 0x2D }, /* BRAILLE PATTERN DOTS-36 -> '-' */ + { 0x25, 0x75 }, /* BRAILLE PATTERN DOTS-136 -> 'u' */ + { 0x26, 0x38 }, /* BRAILLE PATTERN DOTS-236 -> '8' */ + { 0x27, 0x76 }, /* BRAILLE PATTERN DOTS-1236 -> 'v' */ + { 0x28, 0x2E }, /* BRAILLE PATTERN DOTS-46 -> '.' */ + { 0x29, 0x25 }, /* BRAILLE PATTERN DOTS-146 -> '%' */ + { 0x2A, 0x5B }, /* BRAILLE PATTERN DOTS-246 -> '[' */ + { 0x2B, 0x24 }, /* BRAILLE PATTERN DOTS-1246 -> '$' */ + { 0x2C, 0x2B }, /* BRAILLE PATTERN DOTS-346 -> '+' */ + { 0x2D, 0x78 }, /* BRAILLE PATTERN DOTS-1346 -> 'x' */ + { 0x2E, 0x21 }, /* BRAILLE PATTERN DOTS-2346 -> '!' */ + { 0x2F, 0x26 }, /* BRAILLE PATTERN DOTS-12346 -> '&' */ + { 0x30, 0x3B }, /* BRAILLE PATTERN DOTS-56 -> ';' */ + { 0x31, 0x3A }, /* BRAILLE PATTERN DOTS-156 -> ':' */ + { 0x32, 0x34 }, /* BRAILLE PATTERN DOTS-256 -> '4' */ + { 0x33, 0x5C }, /* BRAILLE PATTERN DOTS-1256 -> '\' */ + { 0x34, 0x30 }, /* BRAILLE PATTERN DOTS-356 -> '0' */ + { 0x35, 0x7A }, /* BRAILLE PATTERN DOTS-1356 -> 'z' */ + { 0x36, 0x37 }, /* BRAILLE PATTERN DOTS-2356 -> '7' */ + { 0x37, 0x28 }, /* BRAILLE PATTERN DOTS-12356 -> '(' */ + { 0x38, 0x5F }, /* BRAILLE PATTERN DOTS-456 -> '_' */ + { 0x39, 0x3F }, /* BRAILLE PATTERN DOTS-1456 -> '?' */ + { 0x3A, 0x77 }, /* BRAILLE PATTERN DOTS-2456 -> 'w' */ + { 0x3B, 0x5D }, /* BRAILLE PATTERN DOTS-12456 -> ']' */ + { 0x3C, 0x23 }, /* BRAILLE PATTERN DOTS-3456 -> '#' */ + { 0x3D, 0x79 }, /* BRAILLE PATTERN DOTS-13456 -> 'y' */ + { 0x3E, 0x29 }, /* BRAILLE PATTERN DOTS-23456 -> ')' */ + { 0x3F, 0x3D }, /* BRAILLE PATTERN DOTS-123456 -> '=' */ + /* Entries for page 0x29 */ + { 0x83, 0x7B }, /* LEFT WHITE CURLY BRACKET -> '{' */ + /* Entries for page 0x2C */ + { 0x60, 0x4C }, /* LATIN CAPITAL LETTER L WITH DOUBLE BAR -> 'L' */ + { 0x61, 0x6C }, /* LATIN SMALL LETTER L WITH DOUBLE BAR -> 'l' */ + { 0x62, 0x4C }, /* LATIN CAPITAL LETTER L WITH MIDDLE TILDE -> 'L' */ + { 0x63, 0x50 }, /* LATIN CAPITAL LETTER P WITH STROKE -> 'P' */ + { 0x64, 0x52 }, /* LATIN CAPITAL LETTER R WITH TAIL -> 'R' */ + { 0x65, 0x61 }, /* LATIN SMALL LETTER A WITH STROKE -> 'a' */ + { 0x66, 0x74 }, /* LATIN SMALL LETTER T WITH DIAGONAL STROKE -> 't' */ + { 0x67, 0x48 }, /* LATIN CAPITAL LETTER H WITH DESCENDER -> 'H' */ + { 0x68, 0x68 }, /* LATIN SMALL LETTER H WITH DESCENDER -> 'h' */ + { 0x69, 0x4B }, /* LATIN CAPITAL LETTER K WITH DESCENDER -> 'K' */ + { 0x6A, 0x6B }, /* LATIN SMALL LETTER K WITH DESCENDER -> 'k' */ + { 0x6B, 0x5A }, /* LATIN CAPITAL LETTER Z WITH DESCENDER -> 'Z' */ + { 0x6C, 0x7A }, /* LATIN SMALL LETTER Z WITH DESCENDER -> 'z' */ + { 0x6E, 0x4D }, /* LATIN CAPITAL LETTER M WITH HOOK -> 'M' */ + { 0x6F, 0x41 }, /* LATIN CAPITAL LETTER TURNED A -> 'A' */ + /* Entries for page 0x2E */ + { 0x00, 0x72 }, /* RIGHT ANGLE SUBSTITUTION MARKER -> 'r' */ + { 0x06, 0x54 }, /* RAISED INTERPOLATION MARKER -> 'T' */ + { 0x09, 0x73 }, /* LEFT TRANSPOSITION BRACKET -> 's' */ + { 0x0C, 0x5C }, /* LEFT RAISED OMISSION BRACKET -> '\' */ + { 0x0D, 0x2F }, /* RIGHT RAISED OMISSION BRACKET -> '/' */ + { 0x12, 0x3E }, /* HYPODIASTOLE -> '>' */ + { 0x13, 0x25 }, /* DOTTED OBELOS -> '%' */ + { 0x16, 0x3E }, /* DOTTED RIGHT-POINTING ANGLE -> '>' */ + { 0x17, 0x3D }, /* DOUBLE OBLIQUE HYPHEN -> '=' */ + { 0x19, 0x2F }, /* PALM BRANCH -> '/' */ + { 0x1A, 0x2D }, /* HYPHEN WITH DIAERESIS -> '-' */ + { 0x1B, 0x7E }, /* TILDE WITH RING ABOVE -> '~' */ + { 0x1C, 0x5C }, /* LEFT LOW PARAPHRASE BRACKET -> '\' */ + { 0x1D, 0x2F }, /* RIGHT LOW PARAPHRASE BRACKET -> '/' */ + { 0x1E, 0x7E }, /* TILDE WITH DOT ABOVE -> '~' */ + { 0x1F, 0x7E }, /* TILDE WITH DOT BELOW -> '~' */ + { 0x2E, 0x3F }, /* REVERSED QUESTION MARK -> '?' */ + { 0x2F, 0x27 }, /* VERTICAL TILDE -> ''' */ + { 0x30, 0x6F }, /* RING POINT -> 'o' */ + { 0x31, 0x2E }, /* WORD SEPARATOR MIDDLE DOT -> '.' */ + { 0x32, 0x2C }, /* TURNED COMMA -> ',' */ + { 0x33, 0x2E }, /* RAISED DOT -> '.' */ + { 0x34, 0x2C }, /* RAISED COMMA -> ',' */ + { 0x35, 0x3B }, /* TURNED SEMICOLON -> ';' */ + { 0x3C, 0x78 }, /* STENOGRAPHIC FULL STOP -> 'x' */ + { 0x3D, 0x7C }, /* VERTICAL SIX DOTS -> '|' */ + { 0x40, 0x3D }, /* DOUBLE HYPHEN -> '=' */ + { 0x41, 0x2C }, /* REVERSED COMMA -> ',' */ + { 0x42, 0x22 }, /* DOUBLE LOW-REVERSED-9 QUOTATION MARK -> '"' */ + /* Entries for page 0x30 */ + { 0x00, 0x20 }, /* IDEOGRAPHIC SPACE -> ' ' */ + { 0x03, 0x22 }, /* DITTO MARK -> '"' */ + { 0x05, 0x22 }, /* IDEOGRAPHIC ITERATION MARK -> '"' */ + { 0x06, 0x2F }, /* IDEOGRAPHIC CLOSING MARK -> '/' */ + { 0x07, 0x30 }, /* IDEOGRAPHIC NUMBER ZERO -> '0' */ + { 0x08, 0x3C }, /* LEFT ANGLE BRACKET -> '<' */ + { 0x0C, 0x5B }, /* LEFT CORNER BRACKET -> '[' */ + { 0x0E, 0x7B }, /* LEFT WHITE CORNER BRACKET -> '{' */ + { 0x12, 0x40 }, /* POSTAL MARK -> '@' */ + { 0x14, 0x5B }, /* LEFT TORTOISE SHELL BRACKET -> '[' */ + { 0x20, 0x40 }, /* POSTAL MARK FACE -> '@' */ + { 0x21, 0x31 }, /* HANGZHOU NUMERAL ONE -> '1' */ + { 0x22, 0x32 }, /* HANGZHOU NUMERAL TWO -> '2' */ + { 0x23, 0x33 }, /* HANGZHOU NUMERAL THREE -> '3' */ + { 0x24, 0x34 }, /* HANGZHOU NUMERAL FOUR -> '4' */ + { 0x25, 0x35 }, /* HANGZHOU NUMERAL FIVE -> '5' */ + { 0x26, 0x36 }, /* HANGZHOU NUMERAL SIX -> '6' */ + { 0x27, 0x37 }, /* HANGZHOU NUMERAL SEVEN -> '7' */ + { 0x28, 0x38 }, /* HANGZHOU NUMERAL EIGHT -> '8' */ + { 0x29, 0x39 }, /* HANGZHOU NUMERAL NINE -> '9' */ + { 0x30, 0x7E }, /* WAVY DASH -> '~' */ + { 0x31, 0x00 }, /* VERTICAL KANA REPEAT MARK -> ... */ + { 0x34, 0x2B }, /* VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF -> '+' */ + { 0x36, 0x40 }, /* CIRCLED POSTAL MARK -> '@' */ + { 0x41, 0x61 }, /* HIRAGANA LETTER SMALL A -> 'a' */ + { 0x42, 0x61 }, /* HIRAGANA LETTER A -> 'a' */ + { 0x43, 0x69 }, /* HIRAGANA LETTER SMALL I -> 'i' */ + { 0x44, 0x69 }, /* HIRAGANA LETTER I -> 'i' */ + { 0x45, 0x75 }, /* HIRAGANA LETTER SMALL U -> 'u' */ + { 0x46, 0x75 }, /* HIRAGANA LETTER U -> 'u' */ + { 0x47, 0x65 }, /* HIRAGANA LETTER SMALL E -> 'e' */ + { 0x48, 0x65 }, /* HIRAGANA LETTER E -> 'e' */ + { 0x49, 0x6F }, /* HIRAGANA LETTER SMALL O -> 'o' */ + { 0x4A, 0x6F }, /* HIRAGANA LETTER O -> 'o' */ + { 0x93, 0x6E }, /* HIRAGANA LETTER N -> 'n' */ + { 0x9D, 0x22 }, /* HIRAGANA ITERATION MARK -> '"' */ + { 0x9E, 0x22 }, /* HIRAGANA VOICED ITERATION MARK -> '"' */ + { 0xA0, 0x3D }, /* KATAKANA-HIRAGANA DOUBLE HYPHEN -> '=' */ + { 0xA1, 0x61 }, /* KATAKANA LETTER SMALL A -> 'a' */ + { 0xA2, 0x61 }, /* KATAKANA LETTER A -> 'a' */ + { 0xA3, 0x69 }, /* KATAKANA LETTER SMALL I -> 'i' */ + { 0xA4, 0x69 }, /* KATAKANA LETTER I -> 'i' */ + { 0xA5, 0x75 }, /* KATAKANA LETTER SMALL U -> 'u' */ + { 0xA6, 0x75 }, /* KATAKANA LETTER U -> 'u' */ + { 0xA7, 0x65 }, /* KATAKANA LETTER SMALL E -> 'e' */ + { 0xA8, 0x65 }, /* KATAKANA LETTER E -> 'e' */ + { 0xA9, 0x6F }, /* KATAKANA LETTER SMALL O -> 'o' */ + { 0xAA, 0x6F }, /* KATAKANA LETTER O -> 'o' */ + { 0xF3, 0x6E }, /* KATAKANA LETTER N -> 'n' */ + { 0xFB, 0x2A }, /* KATAKANA MIDDLE DOT -> '*' */ + { 0xFC, 0x2D }, /* KATAKANA-HIRAGANA PROLONGED SOUND MARK -> '-' */ + { 0xFD, 0x22 }, /* KATAKANA ITERATION MARK -> '"' */ + { 0xFE, 0x22 }, /* KATAKANA VOICED ITERATION MARK -> '"' */ + /* Entries for page 0x31 */ + { 0x05, 0x42 }, /* BOPOMOFO LETTER B -> 'B' */ + { 0x06, 0x50 }, /* BOPOMOFO LETTER P -> 'P' */ + { 0x07, 0x4D }, /* BOPOMOFO LETTER M -> 'M' */ + { 0x08, 0x46 }, /* BOPOMOFO LETTER F -> 'F' */ + { 0x09, 0x44 }, /* BOPOMOFO LETTER D -> 'D' */ + { 0x0A, 0x54 }, /* BOPOMOFO LETTER T -> 'T' */ + { 0x0B, 0x4E }, /* BOPOMOFO LETTER N -> 'N' */ + { 0x0C, 0x4C }, /* BOPOMOFO LETTER L -> 'L' */ + { 0x0D, 0x47 }, /* BOPOMOFO LETTER G -> 'G' */ + { 0x0E, 0x4B }, /* BOPOMOFO LETTER K -> 'K' */ + { 0x0F, 0x48 }, /* BOPOMOFO LETTER H -> 'H' */ + { 0x10, 0x4A }, /* BOPOMOFO LETTER J -> 'J' */ + { 0x11, 0x51 }, /* BOPOMOFO LETTER Q -> 'Q' */ + { 0x12, 0x58 }, /* BOPOMOFO LETTER X -> 'X' */ + { 0x16, 0x52 }, /* BOPOMOFO LETTER R -> 'R' */ + { 0x17, 0x5A }, /* BOPOMOFO LETTER Z -> 'Z' */ + { 0x18, 0x43 }, /* BOPOMOFO LETTER C -> 'C' */ + { 0x19, 0x53 }, /* BOPOMOFO LETTER S -> 'S' */ + { 0x1A, 0x41 }, /* BOPOMOFO LETTER A -> 'A' */ + { 0x1B, 0x4F }, /* BOPOMOFO LETTER O -> 'O' */ + { 0x1C, 0x45 }, /* BOPOMOFO LETTER E -> 'E' */ + { 0x27, 0x49 }, /* BOPOMOFO LETTER I -> 'I' */ + { 0x28, 0x55 }, /* BOPOMOFO LETTER U -> 'U' */ + { 0x2A, 0x56 }, /* BOPOMOFO LETTER V -> 'V' */ + { 0x31, 0x67 }, /* HANGUL LETTER KIYEOK -> 'g' */ + { 0x34, 0x6E }, /* HANGUL LETTER NIEUN -> 'n' */ + { 0x37, 0x64 }, /* HANGUL LETTER TIKEUT -> 'd' */ + { 0x39, 0x72 }, /* HANGUL LETTER RIEUL -> 'r' */ + { 0x41, 0x6D }, /* HANGUL LETTER MIEUM -> 'm' */ + { 0x42, 0x62 }, /* HANGUL LETTER PIEUP -> 'b' */ + { 0x45, 0x73 }, /* HANGUL LETTER SIOS -> 's' */ + { 0x48, 0x6A }, /* HANGUL LETTER CIEUC -> 'j' */ + { 0x4A, 0x63 }, /* HANGUL LETTER CHIEUCH -> 'c' */ + { 0x4B, 0x6B }, /* HANGUL LETTER KHIEUKH -> 'k' */ + { 0x4C, 0x74 }, /* HANGUL LETTER THIEUTH -> 't' */ + { 0x4D, 0x70 }, /* HANGUL LETTER PHIEUPH -> 'p' */ + { 0x4E, 0x68 }, /* HANGUL LETTER HIEUH -> 'h' */ + { 0x4F, 0x61 }, /* HANGUL LETTER A -> 'a' */ + { 0x54, 0x65 }, /* HANGUL LETTER E -> 'e' */ + { 0x57, 0x6F }, /* HANGUL LETTER O -> 'o' */ + { 0x5C, 0x75 }, /* HANGUL LETTER U -> 'u' */ + { 0x63, 0x69 }, /* HANGUL LETTER I -> 'i' */ + { 0x7F, 0x5A }, /* HANGUL LETTER PANSIOS -> 'Z' */ + { 0x81, 0x4E }, /* HANGUL LETTER YESIEUNG -> 'N' */ + { 0x86, 0x51 }, /* HANGUL LETTER YEORINHIEUH -> 'Q' */ + { 0x8D, 0x55 }, /* HANGUL LETTER ARAEA -> 'U' */ + { 0xB4, 0x50 }, /* BOPOMOFO FINAL LETTER P -> 'P' */ + { 0xB5, 0x54 }, /* BOPOMOFO FINAL LETTER T -> 'T' */ + { 0xB6, 0x4B }, /* BOPOMOFO FINAL LETTER K -> 'K' */ + { 0xB7, 0x48 }, /* BOPOMOFO FINAL LETTER H -> 'H' */ + /* Entries for page 0x32 */ + { 0xD0, 0x61 }, /* CIRCLED KATAKANA A -> 'a' */ + { 0xD1, 0x69 }, /* CIRCLED KATAKANA I -> 'i' */ + { 0xD2, 0x75 }, /* CIRCLED KATAKANA U -> 'u' */ + { 0xD3, 0x75 }, /* CIRCLED KATAKANA E -> 'u' */ + { 0xD4, 0x6F }, /* CIRCLED KATAKANA O -> 'o' */ + /* Entries for page 0xA0 */ + { 0x02, 0x69 }, /* YI SYLLABLE I -> 'i' */ + { 0x0A, 0x61 }, /* YI SYLLABLE A -> 'a' */ + { 0x11, 0x6F }, /* YI SYLLABLE O -> 'o' */ + { 0x14, 0x65 }, /* YI SYLLABLE E -> 'e' */ + /* Entries for page 0xC5 */ + { 0x44, 0x61 }, /* HANGUL SYLLABLE A -> 'a' */ + { 0xD0, 0x65 }, /* HANGUL SYLLABLE E -> 'e' */ + /* Entries for page 0xC6 */ + { 0x24, 0x6F }, /* HANGUL SYLLABLE O -> 'o' */ + { 0xB0, 0x75 }, /* HANGUL SYLLABLE U -> 'u' */ + /* Entries for page 0xC7 */ + { 0x74, 0x69 }, /* HANGUL SYLLABLE I -> 'i' */ + /* Entries for page 0xFB */ + { 0x1D, 0x69 }, /* HEBREW LETTER YOD WITH HIRIQ -> 'i' */ + { 0x20, 0x60 }, /* HEBREW LETTER ALTERNATIVE AYIN -> '`' */ + { 0x21, 0x41 }, /* HEBREW LETTER WIDE ALEF -> 'A' */ + { 0x22, 0x64 }, /* HEBREW LETTER WIDE DALET -> 'd' */ + { 0x23, 0x68 }, /* HEBREW LETTER WIDE HE -> 'h' */ + { 0x25, 0x6C }, /* HEBREW LETTER WIDE LAMED -> 'l' */ + { 0x26, 0x6D }, /* HEBREW LETTER WIDE FINAL MEM -> 'm' */ + { 0x27, 0x72 }, /* HEBREW LETTER WIDE RESH -> 'r' */ + { 0x28, 0x74 }, /* HEBREW LETTER WIDE TAV -> 't' */ + { 0x29, 0x2B }, /* HEBREW LETTER ALTERNATIVE PLUS SIGN -> '+' */ + { 0x2B, 0x53 }, /* HEBREW LETTER SHIN WITH SIN DOT -> 'S' */ + { 0x2D, 0x53 }, /* HEBREW LETTER SHIN WITH DAGESH AND SIN DOT -> 'S' */ + { 0x2E, 0x61 }, /* HEBREW LETTER ALEF WITH PATAH -> 'a' */ + { 0x2F, 0x61 }, /* HEBREW LETTER ALEF WITH QAMATS -> 'a' */ + { 0x30, 0x41 }, /* HEBREW LETTER ALEF WITH MAPIQ -> 'A' */ + { 0x31, 0x62 }, /* HEBREW LETTER BET WITH DAGESH -> 'b' */ + { 0x32, 0x67 }, /* HEBREW LETTER GIMEL WITH DAGESH -> 'g' */ + { 0x33, 0x64 }, /* HEBREW LETTER DALET WITH DAGESH -> 'd' */ + { 0x34, 0x68 }, /* HEBREW LETTER HE WITH MAPIQ -> 'h' */ + { 0x35, 0x76 }, /* HEBREW LETTER VAV WITH DAGESH -> 'v' */ + { 0x36, 0x7A }, /* HEBREW LETTER ZAYIN WITH DAGESH -> 'z' */ + { 0x38, 0x74 }, /* HEBREW LETTER TET WITH DAGESH -> 't' */ + { 0x39, 0x79 }, /* HEBREW LETTER YOD WITH DAGESH -> 'y' */ + { 0x3C, 0x6C }, /* HEBREW LETTER LAMED WITH DAGESH -> 'l' */ + { 0x3E, 0x6D }, /* HEBREW LETTER MEM WITH DAGESH -> 'm' */ + { 0x40, 0x6E }, /* HEBREW LETTER NUN WITH DAGESH -> 'n' */ + { 0x41, 0x73 }, /* HEBREW LETTER SAMEKH WITH DAGESH -> 's' */ + { 0x43, 0x70 }, /* HEBREW LETTER FINAL PE WITH DAGESH -> 'p' */ + { 0x44, 0x70 }, /* HEBREW LETTER PE WITH DAGESH -> 'p' */ + { 0x47, 0x6B }, /* HEBREW LETTER QOF WITH DAGESH -> 'k' */ + { 0x48, 0x72 }, /* HEBREW LETTER RESH WITH DAGESH -> 'r' */ + { 0x4A, 0x74 }, /* HEBREW LETTER TAV WITH DAGESH -> 't' */ + { 0x4B, 0x6F }, /* HEBREW LETTER VAV WITH HOLAM -> 'o' */ + { 0x4C, 0x76 }, /* HEBREW LETTER BET WITH RAFE -> 'v' */ + { 0x4E, 0x66 }, /* HEBREW LETTER PE WITH RAFE -> 'f' */ + /* Entries for page 0xFE */ + { 0x23, 0x7E }, /* COMBINING DOUBLE TILDE RIGHT HALF -> '~' */ + { 0x32, 0x2D }, /* PRESENTATION FORM FOR VERTICAL EN DASH -> '-' */ + { 0x33, 0x5F }, /* PRESENTATION FORM FOR VERTICAL LOW LINE -> '_' */ + { 0x34, 0x5F }, /* PRESENTATION FORM FOR VERTICAL WAVY LOW LINE -> '_' */ + { 0x35, 0x28 }, /* PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS -> '(' */ + { 0x37, 0x7B }, /* PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET -> '{' */ + { 0x39, 0x5B }, /* PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET -> '[' */ + { 0x3F, 0x3C }, /* PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET -> '<' */ + { 0x41, 0x5B }, /* PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET -> '[' */ + { 0x43, 0x7B }, /* PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET -> '{' */ + { 0x44, 0x7D }, /* PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET -> '}' */ + { 0x50, 0x2C }, /* SMALL COMMA -> ',' */ + { 0x51, 0x2C }, /* SMALL IDEOGRAPHIC COMMA -> ',' */ + { 0x52, 0x2E }, /* SMALL FULL STOP -> '.' */ + { 0x54, 0x3B }, /* SMALL SEMICOLON -> ';' */ + { 0x55, 0x3A }, /* SMALL COLON -> ':' */ + { 0x56, 0x3F }, /* SMALL QUESTION MARK -> '?' */ + { 0x57, 0x21 }, /* SMALL EXCLAMATION MARK -> '!' */ + { 0x58, 0x2D }, /* SMALL EM DASH -> '-' */ + { 0x59, 0x28 }, /* SMALL LEFT PARENTHESIS -> '(' */ + { 0x5A, 0x29 }, /* SMALL RIGHT PARENTHESIS -> ')' */ + { 0x5B, 0x7B }, /* SMALL LEFT CURLY BRACKET -> '{' */ + { 0x5C, 0x7D }, /* SMALL RIGHT CURLY BRACKET -> '}' */ + { 0x5D, 0x7B }, /* SMALL LEFT TORTOISE SHELL BRACKET -> '{' */ + { 0x5E, 0x7D }, /* SMALL RIGHT TORTOISE SHELL BRACKET -> '}' */ + { 0x5F, 0x23 }, /* SMALL NUMBER SIGN -> '#' */ + { 0x60, 0x26 }, /* SMALL AMPERSAND -> '&' */ + { 0x61, 0x2A }, /* SMALL ASTERISK -> '*' */ + { 0x62, 0x2B }, /* SMALL PLUS SIGN -> '+' */ + { 0x63, 0x2D }, /* SMALL HYPHEN-MINUS -> '-' */ + { 0x64, 0x3C }, /* SMALL LESS-THAN SIGN -> '<' */ + { 0x65, 0x3E }, /* SMALL GREATER-THAN SIGN -> '>' */ + { 0x66, 0x3D }, /* SMALL EQUALS SIGN -> '=' */ + { 0x68, 0x5C }, /* SMALL REVERSE SOLIDUS -> '\' */ + { 0x69, 0x24 }, /* SMALL DOLLAR SIGN -> '$' */ + { 0x6A, 0x25 }, /* SMALL PERCENT SIGN -> '%' */ + { 0x6B, 0x40 }, /* SMALL COMMERCIAL AT -> '@' */ + /* Entries for page 0xFF */ + { 0x61, 0x2E }, /* HALFWIDTH IDEOGRAPHIC FULL STOP -> '.' */ + { 0x62, 0x5B }, /* HALFWIDTH LEFT CORNER BRACKET -> '[' */ + { 0x63, 0x5D }, /* HALFWIDTH RIGHT CORNER BRACKET -> ']' */ + { 0x64, 0x2C }, /* HALFWIDTH IDEOGRAPHIC COMMA -> ',' */ + { 0x65, 0x2A }, /* HALFWIDTH KATAKANA MIDDLE DOT -> '*' */ + { 0x67, 0x61 }, /* HALFWIDTH KATAKANA LETTER SMALL A -> 'a' */ + { 0x68, 0x69 }, /* HALFWIDTH KATAKANA LETTER SMALL I -> 'i' */ + { 0x69, 0x75 }, /* HALFWIDTH KATAKANA LETTER SMALL U -> 'u' */ + { 0x6A, 0x65 }, /* HALFWIDTH KATAKANA LETTER SMALL E -> 'e' */ + { 0x6B, 0x6F }, /* HALFWIDTH KATAKANA LETTER SMALL O -> 'o' */ + { 0x70, 0x2B }, /* HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK -> '+' */ + { 0x71, 0x61 }, /* HALFWIDTH KATAKANA LETTER A -> 'a' */ + { 0x72, 0x69 }, /* HALFWIDTH KATAKANA LETTER I -> 'i' */ + { 0x73, 0x75 }, /* HALFWIDTH KATAKANA LETTER U -> 'u' */ + { 0x74, 0x65 }, /* HALFWIDTH KATAKANA LETTER E -> 'e' */ + { 0x75, 0x6F }, /* HALFWIDTH KATAKANA LETTER O -> 'o' */ + { 0x9D, 0x6E }, /* HALFWIDTH KATAKANA LETTER N -> 'n' */ + { 0x9E, 0x3A }, /* HALFWIDTH KATAKANA VOICED SOUND MARK -> ':' */ + { 0x9F, 0x3B }, /* HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK -> ';' */ + { 0xA1, 0x67 }, /* HALFWIDTH HANGUL LETTER KIYEOK -> 'g' */ + { 0xA4, 0x6E }, /* HALFWIDTH HANGUL LETTER NIEUN -> 'n' */ + { 0xA7, 0x64 }, /* HALFWIDTH HANGUL LETTER TIKEUT -> 'd' */ + { 0xA9, 0x72 }, /* HALFWIDTH HANGUL LETTER RIEUL -> 'r' */ + { 0xB1, 0x6D }, /* HALFWIDTH HANGUL LETTER MIEUM -> 'm' */ + { 0xB2, 0x62 }, /* HALFWIDTH HANGUL LETTER PIEUP -> 'b' */ + { 0xB5, 0x73 }, /* HALFWIDTH HANGUL LETTER SIOS -> 's' */ + { 0xB8, 0x6A }, /* HALFWIDTH HANGUL LETTER CIEUC -> 'j' */ + { 0xBA, 0x63 }, /* HALFWIDTH HANGUL LETTER CHIEUCH -> 'c' */ + { 0xBB, 0x6B }, /* HALFWIDTH HANGUL LETTER KHIEUKH -> 'k' */ + { 0xBC, 0x74 }, /* HALFWIDTH HANGUL LETTER THIEUTH -> 't' */ + { 0xBD, 0x70 }, /* HALFWIDTH HANGUL LETTER PHIEUPH -> 'p' */ + { 0xBE, 0x68 }, /* HALFWIDTH HANGUL LETTER HIEUH -> 'h' */ + { 0xC2, 0x61 }, /* HALFWIDTH HANGUL LETTER A -> 'a' */ + { 0xC7, 0x65 }, /* HALFWIDTH HANGUL LETTER E -> 'e' */ + { 0xCC, 0x6F }, /* HALFWIDTH HANGUL LETTER O -> 'o' */ + { 0xD3, 0x75 }, /* HALFWIDTH HANGUL LETTER U -> 'u' */ + { 0xDC, 0x69 }, /* HALFWIDTH HANGUL LETTER I -> 'i' */ + { 0xE2, 0x21 }, /* FULLWIDTH NOT SIGN -> '!' */ + { 0xE3, 0x2D }, /* FULLWIDTH MACRON -> '-' */ + { 0xE4, 0x7C }, /* FULLWIDTH BROKEN BAR -> '|' */ + { 0xE8, 0x7C }, /* HALFWIDTH FORMS LIGHT VERTICAL -> '|' */ + { 0xE9, 0x3C }, /* HALFWIDTH LEFTWARDS ARROW -> '<' */ + { 0xEA, 0x5E }, /* HALFWIDTH UPWARDS ARROW -> '^' */ + { 0xEB, 0x3E }, /* HALFWIDTH RIGHTWARDS ARROW -> '>' */ + { 0xEC, 0x76 }, /* HALFWIDTH DOWNWARDS ARROW -> 'v' */ + { 0xED, 0x23 }, /* HALFWIDTH BLACK SQUARE -> '#' */ + { 0xEE, 0x4F }, /* HALFWIDTH WHITE CIRCLE -> 'O' */ + { 0xF9, 0x7B }, /* INTERLINEAR ANNOTATION ANCHOR -> '{' */ + { 0xFA, 0x7C }, /* INTERLINEAR ANNOTATION SEPARATOR -> '|' */ + { 0xFB, 0x7D }, /* INTERLINEAR ANNOTATION TERMINATOR -> '}' */ +}; + +#define UCS_PAGE_ENTRY_RANGE_MARKER 0 diff --git a/drivers/tty/vt/ucs_recompose_table.h_shipped b/drivers/tty/vt/ucs_recompose_table.h_shipped new file mode 100644 index 000000000000..bd91edde5d19 --- /dev/null +++ b/drivers/tty/vt/ucs_recompose_table.h_shipped @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ucs_recompose_table.h - Unicode character recomposition + * + * Auto-generated by gen_ucs_recompose_table.py + * + * Unicode Version: 16.0.0 + * + * This file contains a table with most commonly used Latin, Greek, and + * Cyrillic recomposition pairs only (71 entries). To generate a table with + * all possible recomposition pairs from the Unicode BMP (1000 entries) + * instead, run: + * + * python gen_ucs_recompose_table.py --full + */ + +/* + * Table of most commonly used Latin, Greek, and Cyrillic recomposition pairs only + * Sorted by base character and then combining mark for binary search + */ +static const struct ucs_recomposition ucs_recomposition_table[] = { + { 0x0041, 0x0300, 0x00C0 }, /* LATIN CAPITAL LETTER A + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER A WITH GRAVE */ + { 0x0041, 0x0301, 0x00C1 }, /* LATIN CAPITAL LETTER A + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER A WITH ACUTE */ + { 0x0041, 0x0302, 0x00C2 }, /* LATIN CAPITAL LETTER A + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ + { 0x0041, 0x0303, 0x00C3 }, /* LATIN CAPITAL LETTER A + COMBINING TILDE = LATIN CAPITAL LETTER A WITH TILDE */ + { 0x0041, 0x0308, 0x00C4 }, /* LATIN CAPITAL LETTER A + COMBINING DIAERESIS = LATIN CAPITAL LETTER A WITH DIAERESIS */ + { 0x0041, 0x030A, 0x00C5 }, /* LATIN CAPITAL LETTER A + COMBINING RING ABOVE = LATIN CAPITAL LETTER A WITH RING ABOVE */ + { 0x0043, 0x0327, 0x00C7 }, /* LATIN CAPITAL LETTER C + COMBINING CEDILLA = LATIN CAPITAL LETTER C WITH CEDILLA */ + { 0x0045, 0x0300, 0x00C8 }, /* LATIN CAPITAL LETTER E + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER E WITH GRAVE */ + { 0x0045, 0x0301, 0x00C9 }, /* LATIN CAPITAL LETTER E + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER E WITH ACUTE */ + { 0x0045, 0x0302, 0x00CA }, /* LATIN CAPITAL LETTER E + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ + { 0x0045, 0x0308, 0x00CB }, /* LATIN CAPITAL LETTER E + COMBINING DIAERESIS = LATIN CAPITAL LETTER E WITH DIAERESIS */ + { 0x0049, 0x0300, 0x00CC }, /* LATIN CAPITAL LETTER I + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER I WITH GRAVE */ + { 0x0049, 0x0301, 0x00CD }, /* LATIN CAPITAL LETTER I + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER I WITH ACUTE */ + { 0x0049, 0x0302, 0x00CE }, /* LATIN CAPITAL LETTER I + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ + { 0x0049, 0x0308, 0x00CF }, /* LATIN CAPITAL LETTER I + COMBINING DIAERESIS = LATIN CAPITAL LETTER I WITH DIAERESIS */ + { 0x004E, 0x0303, 0x00D1 }, /* LATIN CAPITAL LETTER N + COMBINING TILDE = LATIN CAPITAL LETTER N WITH TILDE */ + { 0x004F, 0x0300, 0x00D2 }, /* LATIN CAPITAL LETTER O + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER O WITH GRAVE */ + { 0x004F, 0x0301, 0x00D3 }, /* LATIN CAPITAL LETTER O + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER O WITH ACUTE */ + { 0x004F, 0x0302, 0x00D4 }, /* LATIN CAPITAL LETTER O + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ + { 0x004F, 0x0303, 0x00D5 }, /* LATIN CAPITAL LETTER O + COMBINING TILDE = LATIN CAPITAL LETTER O WITH TILDE */ + { 0x004F, 0x0308, 0x00D6 }, /* LATIN CAPITAL LETTER O + COMBINING DIAERESIS = LATIN CAPITAL LETTER O WITH DIAERESIS */ + { 0x0055, 0x0300, 0x00D9 }, /* LATIN CAPITAL LETTER U + COMBINING GRAVE ACCENT = LATIN CAPITAL LETTER U WITH GRAVE */ + { 0x0055, 0x0301, 0x00DA }, /* LATIN CAPITAL LETTER U + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER U WITH ACUTE */ + { 0x0055, 0x0302, 0x00DB }, /* LATIN CAPITAL LETTER U + COMBINING CIRCUMFLEX ACCENT = LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ + { 0x0055, 0x0308, 0x00DC }, /* LATIN CAPITAL LETTER U + COMBINING DIAERESIS = LATIN CAPITAL LETTER U WITH DIAERESIS */ + { 0x0059, 0x0301, 0x00DD }, /* LATIN CAPITAL LETTER Y + COMBINING ACUTE ACCENT = LATIN CAPITAL LETTER Y WITH ACUTE */ + { 0x0061, 0x0300, 0x00E0 }, /* LATIN SMALL LETTER A + COMBINING GRAVE ACCENT = LATIN SMALL LETTER A WITH GRAVE */ + { 0x0061, 0x0301, 0x00E1 }, /* LATIN SMALL LETTER A + COMBINING ACUTE ACCENT = LATIN SMALL LETTER A WITH ACUTE */ + { 0x0061, 0x0302, 0x00E2 }, /* LATIN SMALL LETTER A + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER A WITH CIRCUMFLEX */ + { 0x0061, 0x0303, 0x00E3 }, /* LATIN SMALL LETTER A + COMBINING TILDE = LATIN SMALL LETTER A WITH TILDE */ + { 0x0061, 0x0308, 0x00E4 }, /* LATIN SMALL LETTER A + COMBINING DIAERESIS = LATIN SMALL LETTER A WITH DIAERESIS */ + { 0x0061, 0x030A, 0x00E5 }, /* LATIN SMALL LETTER A + COMBINING RING ABOVE = LATIN SMALL LETTER A WITH RING ABOVE */ + { 0x0063, 0x0327, 0x00E7 }, /* LATIN SMALL LETTER C + COMBINING CEDILLA = LATIN SMALL LETTER C WITH CEDILLA */ + { 0x0065, 0x0300, 0x00E8 }, /* LATIN SMALL LETTER E + COMBINING GRAVE ACCENT = LATIN SMALL LETTER E WITH GRAVE */ + { 0x0065, 0x0301, 0x00E9 }, /* LATIN SMALL LETTER E + COMBINING ACUTE ACCENT = LATIN SMALL LETTER E WITH ACUTE */ + { 0x0065, 0x0302, 0x00EA }, /* LATIN SMALL LETTER E + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER E WITH CIRCUMFLEX */ + { 0x0065, 0x0308, 0x00EB }, /* LATIN SMALL LETTER E + COMBINING DIAERESIS = LATIN SMALL LETTER E WITH DIAERESIS */ + { 0x0069, 0x0300, 0x00EC }, /* LATIN SMALL LETTER I + COMBINING GRAVE ACCENT = LATIN SMALL LETTER I WITH GRAVE */ + { 0x0069, 0x0301, 0x00ED }, /* LATIN SMALL LETTER I + COMBINING ACUTE ACCENT = LATIN SMALL LETTER I WITH ACUTE */ + { 0x0069, 0x0302, 0x00EE }, /* LATIN SMALL LETTER I + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER I WITH CIRCUMFLEX */ + { 0x0069, 0x0308, 0x00EF }, /* LATIN SMALL LETTER I + COMBINING DIAERESIS = LATIN SMALL LETTER I WITH DIAERESIS */ + { 0x006E, 0x0303, 0x00F1 }, /* LATIN SMALL LETTER N + COMBINING TILDE = LATIN SMALL LETTER N WITH TILDE */ + { 0x006F, 0x0300, 0x00F2 }, /* LATIN SMALL LETTER O + COMBINING GRAVE ACCENT = LATIN SMALL LETTER O WITH GRAVE */ + { 0x006F, 0x0301, 0x00F3 }, /* LATIN SMALL LETTER O + COMBINING ACUTE ACCENT = LATIN SMALL LETTER O WITH ACUTE */ + { 0x006F, 0x0302, 0x00F4 }, /* LATIN SMALL LETTER O + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER O WITH CIRCUMFLEX */ + { 0x006F, 0x0303, 0x00F5 }, /* LATIN SMALL LETTER O + COMBINING TILDE = LATIN SMALL LETTER O WITH TILDE */ + { 0x006F, 0x0308, 0x00F6 }, /* LATIN SMALL LETTER O + COMBINING DIAERESIS = LATIN SMALL LETTER O WITH DIAERESIS */ + { 0x0075, 0x0300, 0x00F9 }, /* LATIN SMALL LETTER U + COMBINING GRAVE ACCENT = LATIN SMALL LETTER U WITH GRAVE */ + { 0x0075, 0x0301, 0x00FA }, /* LATIN SMALL LETTER U + COMBINING ACUTE ACCENT = LATIN SMALL LETTER U WITH ACUTE */ + { 0x0075, 0x0302, 0x00FB }, /* LATIN SMALL LETTER U + COMBINING CIRCUMFLEX ACCENT = LATIN SMALL LETTER U WITH CIRCUMFLEX */ + { 0x0075, 0x0308, 0x00FC }, /* LATIN SMALL LETTER U + COMBINING DIAERESIS = LATIN SMALL LETTER U WITH DIAERESIS */ + { 0x0079, 0x0301, 0x00FD }, /* LATIN SMALL LETTER Y + COMBINING ACUTE ACCENT = LATIN SMALL LETTER Y WITH ACUTE */ + { 0x0079, 0x0308, 0x00FF }, /* LATIN SMALL LETTER Y + COMBINING DIAERESIS = LATIN SMALL LETTER Y WITH DIAERESIS */ + { 0x0391, 0x0301, 0x0386 }, /* GREEK CAPITAL LETTER ALPHA + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x0395, 0x0301, 0x0388 }, /* GREEK CAPITAL LETTER EPSILON + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x0397, 0x0301, 0x0389 }, /* GREEK CAPITAL LETTER ETA + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x0399, 0x0301, 0x038A }, /* GREEK CAPITAL LETTER IOTA + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x039F, 0x0301, 0x038C }, /* GREEK CAPITAL LETTER OMICRON + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x03A5, 0x0301, 0x038E }, /* GREEK CAPITAL LETTER UPSILON + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x03A9, 0x0301, 0x038F }, /* GREEK CAPITAL LETTER OMEGA + COMBINING ACUTE ACCENT = GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x03B1, 0x0301, 0x03AC }, /* GREEK SMALL LETTER ALPHA + COMBINING ACUTE ACCENT = GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x03B5, 0x0301, 0x03AD }, /* GREEK SMALL LETTER EPSILON + COMBINING ACUTE ACCENT = GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x03B7, 0x0301, 0x03AE }, /* GREEK SMALL LETTER ETA + COMBINING ACUTE ACCENT = GREEK SMALL LETTER ETA WITH TONOS */ + { 0x03B9, 0x0301, 0x03AF }, /* GREEK SMALL LETTER IOTA + COMBINING ACUTE ACCENT = GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x03BF, 0x0301, 0x03CC }, /* GREEK SMALL LETTER OMICRON + COMBINING ACUTE ACCENT = GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x03C5, 0x0301, 0x03CD }, /* GREEK SMALL LETTER UPSILON + COMBINING ACUTE ACCENT = GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x03C9, 0x0301, 0x03CE }, /* GREEK SMALL LETTER OMEGA + COMBINING ACUTE ACCENT = GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x0418, 0x0306, 0x0419 }, /* CYRILLIC CAPITAL LETTER I + COMBINING BREVE = CYRILLIC CAPITAL LETTER SHORT I */ + { 0x0423, 0x0306, 0x040E }, /* CYRILLIC CAPITAL LETTER U + COMBINING BREVE = CYRILLIC CAPITAL LETTER SHORT U */ + { 0x0438, 0x0306, 0x0439 }, /* CYRILLIC SMALL LETTER I + COMBINING BREVE = CYRILLIC SMALL LETTER SHORT I */ + { 0x0443, 0x0306, 0x045E }, /* CYRILLIC SMALL LETTER U + COMBINING BREVE = CYRILLIC SMALL LETTER SHORT U */ +}; + +/* + * Boundary values for quick rejection + * These are calculated by analyzing the table during generation + */ +#define UCS_RECOMPOSE_MIN_BASE 0x0041 +#define UCS_RECOMPOSE_MAX_BASE 0x0443 +#define UCS_RECOMPOSE_MIN_MARK 0x0300 +#define UCS_RECOMPOSE_MAX_MARK 0x0327 diff --git a/drivers/tty/vt/ucs_width_table.h_shipped b/drivers/tty/vt/ucs_width_table.h_shipped new file mode 100644 index 000000000000..6fcb8f1d577d --- /dev/null +++ b/drivers/tty/vt/ucs_width_table.h_shipped @@ -0,0 +1,453 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * ucs_width_table.h - Unicode character width + * + * Auto-generated by gen_ucs_width_table.py + * + * Unicode Version: 16.0.0 + */ + +/* Zero-width character ranges (BMP - Basic Multilingual Plane, U+0000 to U+FFFF) */ +static const struct ucs_interval16 ucs_zero_width_bmp_ranges[] = { + { 0x00AD, 0x00AD }, /* SOFT HYPHEN */ + { 0x0300, 0x036F }, /* COMBINING GRAVE ACCENT - COMBINING LATIN SMALL LETTER X */ + { 0x0483, 0x0489 }, /* COMBINING CYRILLIC TITLO - COMBINING CYRILLIC MILLIONS SIGN */ + { 0x0591, 0x05BD }, /* HEBREW ACCENT ETNAHTA - HEBREW POINT METEG */ + { 0x05BF, 0x05BF }, /* HEBREW POINT RAFE */ + { 0x05C1, 0x05C2 }, /* HEBREW POINT SHIN DOT - HEBREW POINT SIN DOT */ + { 0x05C4, 0x05C5 }, /* HEBREW MARK UPPER DOT - HEBREW MARK LOWER DOT */ + { 0x05C7, 0x05C7 }, /* HEBREW POINT QAMATS QATAN */ + { 0x0600, 0x0605 }, /* ARABIC NUMBER SIGN - ARABIC NUMBER MARK ABOVE */ + { 0x0610, 0x061A }, /* ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM - ARABIC SMALL KASRA */ + { 0x061C, 0x061C }, /* ARABIC LETTER MARK */ + { 0x064B, 0x065F }, /* ARABIC FATHATAN - ARABIC WAVY HAMZA BELOW */ + { 0x0670, 0x0670 }, /* ARABIC LETTER SUPERSCRIPT ALEF */ + { 0x06D6, 0x06DD }, /* ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA - ARABIC END OF AYAH */ + { 0x06DF, 0x06E4 }, /* ARABIC SMALL HIGH ROUNDED ZERO - ARABIC SMALL HIGH MADDA */ + { 0x06E7, 0x06E8 }, /* ARABIC SMALL HIGH YEH - ARABIC SMALL HIGH NOON */ + { 0x06EA, 0x06ED }, /* ARABIC EMPTY CENTRE LOW STOP - ARABIC SMALL LOW MEEM */ + { 0x070F, 0x070F }, /* SYRIAC ABBREVIATION MARK */ + { 0x0711, 0x0711 }, /* SYRIAC LETTER SUPERSCRIPT ALAPH */ + { 0x0730, 0x074A }, /* SYRIAC PTHAHA ABOVE - SYRIAC BARREKH */ + { 0x07A6, 0x07B0 }, /* THAANA ABAFILI - THAANA SUKUN */ + { 0x07EB, 0x07F3 }, /* NKO COMBINING SHORT HIGH TONE - NKO COMBINING DOUBLE DOT ABOVE */ + { 0x07FD, 0x07FD }, /* NKO DANTAYALAN */ + { 0x0816, 0x0819 }, /* SAMARITAN MARK IN - SAMARITAN MARK DAGESH */ + { 0x081B, 0x0823 }, /* SAMARITAN MARK EPENTHETIC YUT - SAMARITAN VOWEL SIGN A */ + { 0x0825, 0x0827 }, /* SAMARITAN VOWEL SIGN SHORT A - SAMARITAN VOWEL SIGN U */ + { 0x0829, 0x082D }, /* SAMARITAN VOWEL SIGN LONG I - SAMARITAN MARK NEQUDAA */ + { 0x0859, 0x085B }, /* MANDAIC AFFRICATION MARK - MANDAIC GEMINATION MARK */ + { 0x0890, 0x0891 }, /* ARABIC POUND MARK ABOVE - ARABIC PIASTRE MARK ABOVE */ + { 0x0897, 0x089F }, /* ARABIC PEPET - ARABIC HALF MADDA OVER MADDA */ + { 0x08CA, 0x0903 }, /* ARABIC SMALL HIGH FARSI YEH - DEVANAGARI SIGN VISARGA */ + { 0x093A, 0x093C }, /* DEVANAGARI VOWEL SIGN OE - DEVANAGARI SIGN NUKTA */ + { 0x093E, 0x094F }, /* DEVANAGARI VOWEL SIGN AA - DEVANAGARI VOWEL SIGN AW */ + { 0x0951, 0x0957 }, /* DEVANAGARI STRESS SIGN UDATTA - DEVANAGARI VOWEL SIGN UUE */ + { 0x0962, 0x0963 }, /* DEVANAGARI VOWEL SIGN VOCALIC L - DEVANAGARI VOWEL SIGN VOCALIC LL */ + { 0x0981, 0x0983 }, /* BENGALI SIGN CANDRABINDU - BENGALI SIGN VISARGA */ + { 0x09BC, 0x09BC }, /* BENGALI SIGN NUKTA */ + { 0x09BE, 0x09C4 }, /* BENGALI VOWEL SIGN AA - BENGALI VOWEL SIGN VOCALIC RR */ + { 0x09C7, 0x09C8 }, /* BENGALI VOWEL SIGN E - BENGALI VOWEL SIGN AI */ + { 0x09CB, 0x09CD }, /* BENGALI VOWEL SIGN O - BENGALI SIGN VIRAMA */ + { 0x09D7, 0x09D7 }, /* BENGALI AU LENGTH MARK */ + { 0x09E2, 0x09E3 }, /* BENGALI VOWEL SIGN VOCALIC L - BENGALI VOWEL SIGN VOCALIC LL */ + { 0x09FE, 0x09FE }, /* BENGALI SANDHI MARK */ + { 0x0A01, 0x0A03 }, /* GURMUKHI SIGN ADAK BINDI - GURMUKHI SIGN VISARGA */ + { 0x0A3C, 0x0A3C }, /* GURMUKHI SIGN NUKTA */ + { 0x0A3E, 0x0A42 }, /* GURMUKHI VOWEL SIGN AA - GURMUKHI VOWEL SIGN UU */ + { 0x0A47, 0x0A48 }, /* GURMUKHI VOWEL SIGN EE - GURMUKHI VOWEL SIGN AI */ + { 0x0A4B, 0x0A4D }, /* GURMUKHI VOWEL SIGN OO - GURMUKHI SIGN VIRAMA */ + { 0x0A51, 0x0A51 }, /* GURMUKHI SIGN UDAAT */ + { 0x0A70, 0x0A71 }, /* GURMUKHI TIPPI - GURMUKHI ADDAK */ + { 0x0A75, 0x0A75 }, /* GURMUKHI SIGN YAKASH */ + { 0x0A81, 0x0A83 }, /* GUJARATI SIGN CANDRABINDU - GUJARATI SIGN VISARGA */ + { 0x0ABC, 0x0ABC }, /* GUJARATI SIGN NUKTA */ + { 0x0ABE, 0x0AC5 }, /* GUJARATI VOWEL SIGN AA - GUJARATI VOWEL SIGN CANDRA E */ + { 0x0AC7, 0x0AC9 }, /* GUJARATI VOWEL SIGN E - GUJARATI VOWEL SIGN CANDRA O */ + { 0x0ACB, 0x0ACD }, /* GUJARATI VOWEL SIGN O - GUJARATI SIGN VIRAMA */ + { 0x0AE2, 0x0AE3 }, /* GUJARATI VOWEL SIGN VOCALIC L - GUJARATI VOWEL SIGN VOCALIC LL */ + { 0x0AFA, 0x0AFF }, /* GUJARATI SIGN SUKUN - GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE */ + { 0x0B01, 0x0B03 }, /* ORIYA SIGN CANDRABINDU - ORIYA SIGN VISARGA */ + { 0x0B3C, 0x0B3C }, /* ORIYA SIGN NUKTA */ + { 0x0B3E, 0x0B44 }, /* ORIYA VOWEL SIGN AA - ORIYA VOWEL SIGN VOCALIC RR */ + { 0x0B47, 0x0B48 }, /* ORIYA VOWEL SIGN E - ORIYA VOWEL SIGN AI */ + { 0x0B4B, 0x0B4D }, /* ORIYA VOWEL SIGN O - ORIYA SIGN VIRAMA */ + { 0x0B55, 0x0B57 }, /* ORIYA SIGN OVERLINE - ORIYA AU LENGTH MARK */ + { 0x0B62, 0x0B63 }, /* ORIYA VOWEL SIGN VOCALIC L - ORIYA VOWEL SIGN VOCALIC LL */ + { 0x0B82, 0x0B82 }, /* TAMIL SIGN ANUSVARA */ + { 0x0BBE, 0x0BC2 }, /* TAMIL VOWEL SIGN AA - TAMIL VOWEL SIGN UU */ + { 0x0BC6, 0x0BC8 }, /* TAMIL VOWEL SIGN E - TAMIL VOWEL SIGN AI */ + { 0x0BCA, 0x0BCD }, /* TAMIL VOWEL SIGN O - TAMIL SIGN VIRAMA */ + { 0x0BD7, 0x0BD7 }, /* TAMIL AU LENGTH MARK */ + { 0x0C00, 0x0C04 }, /* TELUGU SIGN COMBINING CANDRABINDU ABOVE - TELUGU SIGN COMBINING ANUSVARA ABOVE */ + { 0x0C3C, 0x0C3C }, /* TELUGU SIGN NUKTA */ + { 0x0C3E, 0x0C44 }, /* TELUGU VOWEL SIGN AA - TELUGU VOWEL SIGN VOCALIC RR */ + { 0x0C46, 0x0C48 }, /* TELUGU VOWEL SIGN E - TELUGU VOWEL SIGN AI */ + { 0x0C4A, 0x0C4D }, /* TELUGU VOWEL SIGN O - TELUGU SIGN VIRAMA */ + { 0x0C55, 0x0C56 }, /* TELUGU LENGTH MARK - TELUGU AI LENGTH MARK */ + { 0x0C62, 0x0C63 }, /* TELUGU VOWEL SIGN VOCALIC L - TELUGU VOWEL SIGN VOCALIC LL */ + { 0x0C81, 0x0C83 }, /* KANNADA SIGN CANDRABINDU - KANNADA SIGN VISARGA */ + { 0x0CBC, 0x0CBC }, /* KANNADA SIGN NUKTA */ + { 0x0CBE, 0x0CC4 }, /* KANNADA VOWEL SIGN AA - KANNADA VOWEL SIGN VOCALIC RR */ + { 0x0CC6, 0x0CC8 }, /* KANNADA VOWEL SIGN E - KANNADA VOWEL SIGN AI */ + { 0x0CCA, 0x0CCD }, /* KANNADA VOWEL SIGN O - KANNADA SIGN VIRAMA */ + { 0x0CD5, 0x0CD6 }, /* KANNADA LENGTH MARK - KANNADA AI LENGTH MARK */ + { 0x0CE2, 0x0CE3 }, /* KANNADA VOWEL SIGN VOCALIC L - KANNADA VOWEL SIGN VOCALIC LL */ + { 0x0CF3, 0x0CF3 }, /* KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT */ + { 0x0D00, 0x0D03 }, /* MALAYALAM SIGN COMBINING ANUSVARA ABOVE - MALAYALAM SIGN VISARGA */ + { 0x0D3B, 0x0D3C }, /* MALAYALAM SIGN VERTICAL BAR VIRAMA - MALAYALAM SIGN CIRCULAR VIRAMA */ + { 0x0D3E, 0x0D44 }, /* MALAYALAM VOWEL SIGN AA - MALAYALAM VOWEL SIGN VOCALIC RR */ + { 0x0D46, 0x0D48 }, /* MALAYALAM VOWEL SIGN E - MALAYALAM VOWEL SIGN AI */ + { 0x0D4A, 0x0D4D }, /* MALAYALAM VOWEL SIGN O - MALAYALAM SIGN VIRAMA */ + { 0x0D57, 0x0D57 }, /* MALAYALAM AU LENGTH MARK */ + { 0x0D62, 0x0D63 }, /* MALAYALAM VOWEL SIGN VOCALIC L - MALAYALAM VOWEL SIGN VOCALIC LL */ + { 0x0D81, 0x0D83 }, /* SINHALA SIGN CANDRABINDU - SINHALA SIGN VISARGAYA */ + { 0x0DCA, 0x0DCA }, /* SINHALA SIGN AL-LAKUNA */ + { 0x0DCF, 0x0DD4 }, /* SINHALA VOWEL SIGN AELA-PILLA - SINHALA VOWEL SIGN KETTI PAA-PILLA */ + { 0x0DD6, 0x0DD6 }, /* SINHALA VOWEL SIGN DIGA PAA-PILLA */ + { 0x0DD8, 0x0DDF }, /* SINHALA VOWEL SIGN GAETTA-PILLA - SINHALA VOWEL SIGN GAYANUKITTA */ + { 0x0DF2, 0x0DF3 }, /* SINHALA VOWEL SIGN DIGA GAETTA-PILLA - SINHALA VOWEL SIGN DIGA GAYANUKITTA */ + { 0x0E31, 0x0E31 }, /* THAI CHARACTER MAI HAN-AKAT */ + { 0x0E34, 0x0E3A }, /* THAI CHARACTER SARA I - THAI CHARACTER PHINTHU */ + { 0x0E47, 0x0E4E }, /* THAI CHARACTER MAITAIKHU - THAI CHARACTER YAMAKKAN */ + { 0x0EB1, 0x0EB1 }, /* LAO VOWEL SIGN MAI KAN */ + { 0x0EB4, 0x0EBC }, /* LAO VOWEL SIGN I - LAO SEMIVOWEL SIGN LO */ + { 0x0EC8, 0x0ECE }, /* LAO TONE MAI EK - LAO YAMAKKAN */ + { 0x0F18, 0x0F19 }, /* TIBETAN ASTROLOGICAL SIGN -KHYUD PA - TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS */ + { 0x0F35, 0x0F35 }, /* TIBETAN MARK NGAS BZUNG NYI ZLA */ + { 0x0F37, 0x0F37 }, /* TIBETAN MARK NGAS BZUNG SGOR RTAGS */ + { 0x0F39, 0x0F39 }, /* TIBETAN MARK TSA -PHRU */ + { 0x0F3E, 0x0F3F }, /* TIBETAN SIGN YAR TSHES - TIBETAN SIGN MAR TSHES */ + { 0x0F71, 0x0F84 }, /* TIBETAN VOWEL SIGN AA - TIBETAN MARK HALANTA */ + { 0x0F86, 0x0F87 }, /* TIBETAN SIGN LCI RTAGS - TIBETAN SIGN YANG RTAGS */ + { 0x0F8D, 0x0F97 }, /* TIBETAN SUBJOINED SIGN LCE TSA CAN - TIBETAN SUBJOINED LETTER JA */ + { 0x0F99, 0x0FBC }, /* TIBETAN SUBJOINED LETTER NYA - TIBETAN SUBJOINED LETTER FIXED-FORM RA */ + { 0x0FC6, 0x0FC6 }, /* TIBETAN SYMBOL PADMA GDAN */ + { 0x102B, 0x103E }, /* MYANMAR VOWEL SIGN TALL AA - MYANMAR CONSONANT SIGN MEDIAL HA */ + { 0x1056, 0x1059 }, /* MYANMAR VOWEL SIGN VOCALIC R - MYANMAR VOWEL SIGN VOCALIC LL */ + { 0x105E, 0x1060 }, /* MYANMAR CONSONANT SIGN MON MEDIAL NA - MYANMAR CONSONANT SIGN MON MEDIAL LA */ + { 0x1062, 0x1064 }, /* MYANMAR VOWEL SIGN SGAW KAREN EU - MYANMAR TONE MARK SGAW KAREN KE PHO */ + { 0x1067, 0x106D }, /* MYANMAR VOWEL SIGN WESTERN PWO KAREN EU - MYANMAR SIGN WESTERN PWO KAREN TONE-5 */ + { 0x1071, 0x1074 }, /* MYANMAR VOWEL SIGN GEBA KAREN I - MYANMAR VOWEL SIGN KAYAH EE */ + { 0x1082, 0x108D }, /* MYANMAR CONSONANT SIGN SHAN MEDIAL WA - MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE */ + { 0x108F, 0x108F }, /* MYANMAR SIGN RUMAI PALAUNG TONE-5 */ + { 0x109A, 0x109D }, /* MYANMAR SIGN KHAMTI TONE-1 - MYANMAR VOWEL SIGN AITON AI */ + { 0x135D, 0x135F }, /* ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK - ETHIOPIC COMBINING GEMINATION MARK */ + { 0x1712, 0x1715 }, /* TAGALOG VOWEL SIGN I - TAGALOG SIGN PAMUDPOD */ + { 0x1732, 0x1734 }, /* HANUNOO VOWEL SIGN I - HANUNOO SIGN PAMUDPOD */ + { 0x1752, 0x1753 }, /* BUHID VOWEL SIGN I - BUHID VOWEL SIGN U */ + { 0x1772, 0x1773 }, /* TAGBANWA VOWEL SIGN I - TAGBANWA VOWEL SIGN U */ + { 0x17B4, 0x17D3 }, /* KHMER VOWEL INHERENT AQ - KHMER SIGN BATHAMASAT */ + { 0x17DD, 0x17DD }, /* KHMER SIGN ATTHACAN */ + { 0x180B, 0x180F }, /* MONGOLIAN FREE VARIATION SELECTOR ONE - MONGOLIAN FREE VARIATION SELECTOR FOUR */ + { 0x1885, 0x1886 }, /* MONGOLIAN LETTER ALI GALI BALUDA - MONGOLIAN LETTER ALI GALI THREE BALUDA */ + { 0x18A9, 0x18A9 }, /* MONGOLIAN LETTER ALI GALI DAGALGA */ + { 0x1920, 0x192B }, /* LIMBU VOWEL SIGN A - LIMBU SUBJOINED LETTER WA */ + { 0x1930, 0x193B }, /* LIMBU SMALL LETTER KA - LIMBU SIGN SA-I */ + { 0x1A17, 0x1A1B }, /* BUGINESE VOWEL SIGN I - BUGINESE VOWEL SIGN AE */ + { 0x1A55, 0x1A5E }, /* TAI THAM CONSONANT SIGN MEDIAL RA - TAI THAM CONSONANT SIGN SA */ + { 0x1A60, 0x1A7C }, /* TAI THAM SIGN SAKOT - TAI THAM SIGN KHUEN-LUE KARAN */ + { 0x1A7F, 0x1A7F }, /* TAI THAM COMBINING CRYPTOGRAMMIC DOT */ + { 0x1AB0, 0x1ACE }, /* COMBINING DOUBLED CIRCUMFLEX ACCENT - COMBINING LATIN SMALL LETTER INSULAR T */ + { 0x1B00, 0x1B04 }, /* BALINESE SIGN ULU RICEM - BALINESE SIGN BISAH */ + { 0x1B34, 0x1B44 }, /* BALINESE SIGN REREKAN - BALINESE ADEG ADEG */ + { 0x1B6B, 0x1B73 }, /* BALINESE MUSICAL SYMBOL COMBINING TEGEH - BALINESE MUSICAL SYMBOL COMBINING GONG */ + { 0x1B80, 0x1B82 }, /* SUNDANESE SIGN PANYECEK - SUNDANESE SIGN PANGWISAD */ + { 0x1BA1, 0x1BAD }, /* SUNDANESE CONSONANT SIGN PAMINGKAL - SUNDANESE CONSONANT SIGN PASANGAN WA */ + { 0x1BE6, 0x1BF3 }, /* BATAK SIGN TOMPI - BATAK PANONGONAN */ + { 0x1C24, 0x1C37 }, /* LEPCHA SUBJOINED LETTER YA - LEPCHA SIGN NUKTA */ + { 0x1CD0, 0x1CD2 }, /* VEDIC TONE KARSHANA - VEDIC TONE PRENKHA */ + { 0x1CD4, 0x1CE8 }, /* VEDIC SIGN YAJURVEDIC MIDLINE SVARITA - VEDIC SIGN VISARGA ANUDATTA WITH TAIL */ + { 0x1CED, 0x1CED }, /* VEDIC SIGN TIRYAK */ + { 0x1CF4, 0x1CF4 }, /* VEDIC TONE CANDRA ABOVE */ + { 0x1CF7, 0x1CF9 }, /* VEDIC SIGN ATIKRAMA - VEDIC TONE DOUBLE RING ABOVE */ + { 0x1DC0, 0x1DFF }, /* COMBINING DOTTED GRAVE ACCENT - COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW */ + { 0x200B, 0x200F }, /* ZERO WIDTH SPACE - RIGHT-TO-LEFT MARK */ + { 0x202A, 0x202E }, /* LEFT-TO-RIGHT EMBEDDING - RIGHT-TO-LEFT OVERRIDE */ + { 0x2060, 0x2064 }, /* WORD JOINER - INVISIBLE PLUS */ + { 0x2066, 0x206F }, /* LEFT-TO-RIGHT ISOLATE - NOMINAL DIGIT SHAPES */ + { 0x20D0, 0x20F0 }, /* COMBINING LEFT HARPOON ABOVE - COMBINING ASTERISK ABOVE */ + { 0x2640, 0x2640 }, /* FEMALE SIGN */ + { 0x2642, 0x2642 }, /* MALE SIGN */ + { 0x26A7, 0x26A7 }, /* MALE WITH STROKE AND MALE AND FEMALE SIGN */ + { 0x2CEF, 0x2CF1 }, /* COPTIC COMBINING NI ABOVE - COPTIC COMBINING SPIRITUS LENIS */ + { 0x2D7F, 0x2D7F }, /* TIFINAGH CONSONANT JOINER */ + { 0x2DE0, 0x2DFF }, /* COMBINING CYRILLIC LETTER BE - COMBINING CYRILLIC LETTER IOTIFIED BIG YUS */ + { 0x302A, 0x302F }, /* IDEOGRAPHIC LEVEL TONE MARK - HANGUL DOUBLE DOT TONE MARK */ + { 0x3099, 0x309A }, /* COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK - COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0xA66F, 0xA672 }, /* COMBINING CYRILLIC VZMET - COMBINING CYRILLIC THOUSAND MILLIONS SIGN */ + { 0xA674, 0xA67D }, /* COMBINING CYRILLIC LETTER UKRAINIAN IE - COMBINING CYRILLIC PAYEROK */ + { 0xA69E, 0xA69F }, /* COMBINING CYRILLIC LETTER EF - COMBINING CYRILLIC LETTER IOTIFIED E */ + { 0xA6F0, 0xA6F1 }, /* BAMUM COMBINING MARK KOQNDON - BAMUM COMBINING MARK TUKWENTIS */ + { 0xA802, 0xA802 }, /* SYLOTI NAGRI SIGN DVISVARA */ + { 0xA806, 0xA806 }, /* SYLOTI NAGRI SIGN HASANTA */ + { 0xA80B, 0xA80B }, /* SYLOTI NAGRI SIGN ANUSVARA */ + { 0xA823, 0xA827 }, /* SYLOTI NAGRI VOWEL SIGN A - SYLOTI NAGRI VOWEL SIGN OO */ + { 0xA82C, 0xA82C }, /* SYLOTI NAGRI SIGN ALTERNATE HASANTA */ + { 0xA880, 0xA881 }, /* SAURASHTRA SIGN ANUSVARA - SAURASHTRA SIGN VISARGA */ + { 0xA8B4, 0xA8C5 }, /* SAURASHTRA CONSONANT SIGN HAARU - SAURASHTRA SIGN CANDRABINDU */ + { 0xA8E0, 0xA8F1 }, /* COMBINING DEVANAGARI DIGIT ZERO - COMBINING DEVANAGARI SIGN AVAGRAHA */ + { 0xA8FF, 0xA8FF }, /* DEVANAGARI VOWEL SIGN AY */ + { 0xA926, 0xA92D }, /* KAYAH LI VOWEL UE - KAYAH LI TONE CALYA PLOPHU */ + { 0xA947, 0xA953 }, /* REJANG VOWEL SIGN I - REJANG VIRAMA */ + { 0xA980, 0xA983 }, /* JAVANESE SIGN PANYANGGA - JAVANESE SIGN WIGNYAN */ + { 0xA9B3, 0xA9C0 }, /* JAVANESE SIGN CECAK TELU - JAVANESE PANGKON */ + { 0xA9E5, 0xA9E5 }, /* MYANMAR SIGN SHAN SAW */ + { 0xAA29, 0xAA36 }, /* CHAM VOWEL SIGN AA - CHAM CONSONANT SIGN WA */ + { 0xAA43, 0xAA43 }, /* CHAM CONSONANT SIGN FINAL NG */ + { 0xAA4C, 0xAA4D }, /* CHAM CONSONANT SIGN FINAL M - CHAM CONSONANT SIGN FINAL H */ + { 0xAA7B, 0xAA7D }, /* MYANMAR SIGN PAO KAREN TONE - MYANMAR SIGN TAI LAING TONE-5 */ + { 0xAAB0, 0xAAB0 }, /* TAI VIET MAI KANG */ + { 0xAAB2, 0xAAB4 }, /* TAI VIET VOWEL I - TAI VIET VOWEL U */ + { 0xAAB7, 0xAAB8 }, /* TAI VIET MAI KHIT - TAI VIET VOWEL IA */ + { 0xAABE, 0xAABF }, /* TAI VIET VOWEL AM - TAI VIET TONE MAI EK */ + { 0xAAC1, 0xAAC1 }, /* TAI VIET TONE MAI THO */ + { 0xAAEB, 0xAAEF }, /* MEETEI MAYEK VOWEL SIGN II - MEETEI MAYEK VOWEL SIGN AAU */ + { 0xAAF5, 0xAAF6 }, /* MEETEI MAYEK VOWEL SIGN VISARGA - MEETEI MAYEK VIRAMA */ + { 0xABE3, 0xABEA }, /* MEETEI MAYEK VOWEL SIGN ONAP - MEETEI MAYEK VOWEL SIGN NUNG */ + { 0xABEC, 0xABED }, /* MEETEI MAYEK LUM IYEK - MEETEI MAYEK APUN IYEK */ + { 0xFB1E, 0xFB1E }, /* HEBREW POINT JUDEO-SPANISH VARIKA */ + { 0xFE00, 0xFE0F }, /* VARIATION SELECTOR-1 - VARIATION SELECTOR-16 */ + { 0xFE20, 0xFE2F }, /* COMBINING LIGATURE LEFT HALF - COMBINING CYRILLIC TITLO RIGHT HALF */ + { 0xFEFF, 0xFEFF }, /* ZERO WIDTH NO-BREAK SPACE */ + { 0xFFF9, 0xFFFB }, /* INTERLINEAR ANNOTATION ANCHOR - INTERLINEAR ANNOTATION TERMINATOR */ +}; + +/* Zero-width character ranges (non-BMP, U+10000 and above) */ +static const struct ucs_interval32 ucs_zero_width_non_bmp_ranges[] = { + { 0x101FD, 0x101FD }, /* PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE */ + { 0x102E0, 0x102E0 }, /* COPTIC EPACT THOUSANDS MARK */ + { 0x10376, 0x1037A }, /* COMBINING OLD PERMIC LETTER AN - COMBINING OLD PERMIC LETTER SII */ + { 0x10A01, 0x10A03 }, /* KHAROSHTHI VOWEL SIGN I - KHAROSHTHI VOWEL SIGN VOCALIC R */ + { 0x10A05, 0x10A06 }, /* KHAROSHTHI VOWEL SIGN E - KHAROSHTHI VOWEL SIGN O */ + { 0x10A0C, 0x10A0F }, /* KHAROSHTHI VOWEL LENGTH MARK - KHAROSHTHI SIGN VISARGA */ + { 0x10A38, 0x10A3A }, /* KHAROSHTHI SIGN BAR ABOVE - KHAROSHTHI SIGN DOT BELOW */ + { 0x10A3F, 0x10A3F }, /* KHAROSHTHI VIRAMA */ + { 0x10AE5, 0x10AE6 }, /* MANICHAEAN ABBREVIATION MARK ABOVE - MANICHAEAN ABBREVIATION MARK BELOW */ + { 0x10D24, 0x10D27 }, /* HANIFI ROHINGYA SIGN HARBAHAY - HANIFI ROHINGYA SIGN TASSI */ + { 0x10D69, 0x10D6D }, /* GARAY VOWEL SIGN E - GARAY CONSONANT NASALIZATION MARK */ + { 0x10EAB, 0x10EAC }, /* YEZIDI COMBINING HAMZA MARK - YEZIDI COMBINING MADDA MARK */ + { 0x10EFC, 0x10EFF }, /* ARABIC COMBINING ALEF OVERLAY - ARABIC SMALL LOW WORD MADDA */ + { 0x10F46, 0x10F50 }, /* SOGDIAN COMBINING DOT BELOW - SOGDIAN COMBINING STROKE BELOW */ + { 0x10F82, 0x10F85 }, /* OLD UYGHUR COMBINING DOT ABOVE - OLD UYGHUR COMBINING TWO DOTS BELOW */ + { 0x11000, 0x11002 }, /* BRAHMI SIGN CANDRABINDU - BRAHMI SIGN VISARGA */ + { 0x11038, 0x11046 }, /* BRAHMI VOWEL SIGN AA - BRAHMI VIRAMA */ + { 0x11070, 0x11070 }, /* BRAHMI SIGN OLD TAMIL VIRAMA */ + { 0x11073, 0x11074 }, /* BRAHMI VOWEL SIGN OLD TAMIL SHORT E - BRAHMI VOWEL SIGN OLD TAMIL SHORT O */ + { 0x1107F, 0x11082 }, /* BRAHMI NUMBER JOINER - KAITHI SIGN VISARGA */ + { 0x110B0, 0x110BA }, /* KAITHI VOWEL SIGN AA - KAITHI SIGN NUKTA */ + { 0x110BD, 0x110BD }, /* KAITHI NUMBER SIGN */ + { 0x110C2, 0x110C2 }, /* KAITHI VOWEL SIGN VOCALIC R */ + { 0x110CD, 0x110CD }, /* KAITHI NUMBER SIGN ABOVE */ + { 0x11100, 0x11102 }, /* CHAKMA SIGN CANDRABINDU - CHAKMA SIGN VISARGA */ + { 0x11127, 0x11134 }, /* CHAKMA VOWEL SIGN A - CHAKMA MAAYYAA */ + { 0x11145, 0x11146 }, /* CHAKMA VOWEL SIGN AA - CHAKMA VOWEL SIGN EI */ + { 0x11173, 0x11173 }, /* MAHAJANI SIGN NUKTA */ + { 0x11180, 0x11182 }, /* SHARADA SIGN CANDRABINDU - SHARADA SIGN VISARGA */ + { 0x111B3, 0x111C0 }, /* SHARADA VOWEL SIGN AA - SHARADA SIGN VIRAMA */ + { 0x111C9, 0x111CC }, /* SHARADA SANDHI MARK - SHARADA EXTRA SHORT VOWEL MARK */ + { 0x111CE, 0x111CF }, /* SHARADA VOWEL SIGN PRISHTHAMATRA E - SHARADA SIGN INVERTED CANDRABINDU */ + { 0x1122C, 0x11237 }, /* KHOJKI VOWEL SIGN AA - KHOJKI SIGN SHADDA */ + { 0x1123E, 0x1123E }, /* KHOJKI SIGN SUKUN */ + { 0x11241, 0x11241 }, /* KHOJKI VOWEL SIGN VOCALIC R */ + { 0x112DF, 0x112EA }, /* KHUDAWADI SIGN ANUSVARA - KHUDAWADI SIGN VIRAMA */ + { 0x11300, 0x11303 }, /* GRANTHA SIGN COMBINING ANUSVARA ABOVE - GRANTHA SIGN VISARGA */ + { 0x1133B, 0x1133C }, /* COMBINING BINDU BELOW - GRANTHA SIGN NUKTA */ + { 0x1133E, 0x11344 }, /* GRANTHA VOWEL SIGN AA - GRANTHA VOWEL SIGN VOCALIC RR */ + { 0x11347, 0x11348 }, /* GRANTHA VOWEL SIGN EE - GRANTHA VOWEL SIGN AI */ + { 0x1134B, 0x1134D }, /* GRANTHA VOWEL SIGN OO - GRANTHA SIGN VIRAMA */ + { 0x11357, 0x11357 }, /* GRANTHA AU LENGTH MARK */ + { 0x11362, 0x11363 }, /* GRANTHA VOWEL SIGN VOCALIC L - GRANTHA VOWEL SIGN VOCALIC LL */ + { 0x11366, 0x1136C }, /* COMBINING GRANTHA DIGIT ZERO - COMBINING GRANTHA DIGIT SIX */ + { 0x11370, 0x11374 }, /* COMBINING GRANTHA LETTER A - COMBINING GRANTHA LETTER PA */ + { 0x113B8, 0x113C0 }, /* TULU-TIGALARI VOWEL SIGN AA - TULU-TIGALARI VOWEL SIGN VOCALIC LL */ + { 0x113C2, 0x113C2 }, /* TULU-TIGALARI VOWEL SIGN EE */ + { 0x113C5, 0x113C5 }, /* TULU-TIGALARI VOWEL SIGN AI */ + { 0x113C7, 0x113CA }, /* TULU-TIGALARI VOWEL SIGN OO - TULU-TIGALARI SIGN CANDRA ANUNASIKA */ + { 0x113CC, 0x113D0 }, /* TULU-TIGALARI SIGN ANUSVARA - TULU-TIGALARI CONJOINER */ + { 0x113D2, 0x113D2 }, /* TULU-TIGALARI GEMINATION MARK */ + { 0x113E1, 0x113E2 }, /* TULU-TIGALARI VEDIC TONE SVARITA - TULU-TIGALARI VEDIC TONE ANUDATTA */ + { 0x11435, 0x11446 }, /* NEWA VOWEL SIGN AA - NEWA SIGN NUKTA */ + { 0x1145E, 0x1145E }, /* NEWA SANDHI MARK */ + { 0x114B0, 0x114C3 }, /* TIRHUTA VOWEL SIGN AA - TIRHUTA SIGN NUKTA */ + { 0x115AF, 0x115B5 }, /* SIDDHAM VOWEL SIGN AA - SIDDHAM VOWEL SIGN VOCALIC RR */ + { 0x115B8, 0x115C0 }, /* SIDDHAM VOWEL SIGN E - SIDDHAM SIGN NUKTA */ + { 0x115DC, 0x115DD }, /* SIDDHAM VOWEL SIGN ALTERNATE U - SIDDHAM VOWEL SIGN ALTERNATE UU */ + { 0x11630, 0x11640 }, /* MODI VOWEL SIGN AA - MODI SIGN ARDHACANDRA */ + { 0x116AB, 0x116B7 }, /* TAKRI SIGN ANUSVARA - TAKRI SIGN NUKTA */ + { 0x1171D, 0x1172B }, /* AHOM CONSONANT SIGN MEDIAL LA - AHOM SIGN KILLER */ + { 0x1182C, 0x1183A }, /* DOGRA VOWEL SIGN AA - DOGRA SIGN NUKTA */ + { 0x11930, 0x11935 }, /* DIVES AKURU VOWEL SIGN AA - DIVES AKURU VOWEL SIGN E */ + { 0x11937, 0x11938 }, /* DIVES AKURU VOWEL SIGN AI - DIVES AKURU VOWEL SIGN O */ + { 0x1193B, 0x1193E }, /* DIVES AKURU SIGN ANUSVARA - DIVES AKURU VIRAMA */ + { 0x11940, 0x11940 }, /* DIVES AKURU MEDIAL YA */ + { 0x11942, 0x11943 }, /* DIVES AKURU MEDIAL RA - DIVES AKURU SIGN NUKTA */ + { 0x119D1, 0x119D7 }, /* NANDINAGARI VOWEL SIGN AA - NANDINAGARI VOWEL SIGN VOCALIC RR */ + { 0x119DA, 0x119E0 }, /* NANDINAGARI VOWEL SIGN E - NANDINAGARI SIGN VIRAMA */ + { 0x119E4, 0x119E4 }, /* NANDINAGARI VOWEL SIGN PRISHTHAMATRA E */ + { 0x11A01, 0x11A0A }, /* ZANABAZAR SQUARE VOWEL SIGN I - ZANABAZAR SQUARE VOWEL LENGTH MARK */ + { 0x11A33, 0x11A39 }, /* ZANABAZAR SQUARE FINAL CONSONANT MARK - ZANABAZAR SQUARE SIGN VISARGA */ + { 0x11A3B, 0x11A3E }, /* ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA - ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA */ + { 0x11A47, 0x11A47 }, /* ZANABAZAR SQUARE SUBJOINER */ + { 0x11A51, 0x11A5B }, /* SOYOMBO VOWEL SIGN I - SOYOMBO VOWEL LENGTH MARK */ + { 0x11A8A, 0x11A99 }, /* SOYOMBO FINAL CONSONANT SIGN G - SOYOMBO SUBJOINER */ + { 0x11C2F, 0x11C36 }, /* BHAIKSUKI VOWEL SIGN AA - BHAIKSUKI VOWEL SIGN VOCALIC L */ + { 0x11C38, 0x11C3F }, /* BHAIKSUKI VOWEL SIGN E - BHAIKSUKI SIGN VIRAMA */ + { 0x11C92, 0x11CA7 }, /* MARCHEN SUBJOINED LETTER KA - MARCHEN SUBJOINED LETTER ZA */ + { 0x11CA9, 0x11CB6 }, /* MARCHEN SUBJOINED LETTER YA - MARCHEN SIGN CANDRABINDU */ + { 0x11D31, 0x11D36 }, /* MASARAM GONDI VOWEL SIGN AA - MASARAM GONDI VOWEL SIGN VOCALIC R */ + { 0x11D3A, 0x11D3A }, /* MASARAM GONDI VOWEL SIGN E */ + { 0x11D3C, 0x11D3D }, /* MASARAM GONDI VOWEL SIGN AI - MASARAM GONDI VOWEL SIGN O */ + { 0x11D3F, 0x11D45 }, /* MASARAM GONDI VOWEL SIGN AU - MASARAM GONDI VIRAMA */ + { 0x11D47, 0x11D47 }, /* MASARAM GONDI RA-KARA */ + { 0x11D8A, 0x11D8E }, /* GUNJALA GONDI VOWEL SIGN AA - GUNJALA GONDI VOWEL SIGN UU */ + { 0x11D90, 0x11D91 }, /* GUNJALA GONDI VOWEL SIGN EE - GUNJALA GONDI VOWEL SIGN AI */ + { 0x11D93, 0x11D97 }, /* GUNJALA GONDI VOWEL SIGN OO - GUNJALA GONDI VIRAMA */ + { 0x11EF3, 0x11EF6 }, /* MAKASAR VOWEL SIGN I - MAKASAR VOWEL SIGN O */ + { 0x11F00, 0x11F01 }, /* KAWI SIGN CANDRABINDU - KAWI SIGN ANUSVARA */ + { 0x11F03, 0x11F03 }, /* KAWI SIGN VISARGA */ + { 0x11F34, 0x11F3A }, /* KAWI VOWEL SIGN AA - KAWI VOWEL SIGN VOCALIC R */ + { 0x11F3E, 0x11F42 }, /* KAWI VOWEL SIGN E - KAWI CONJOINER */ + { 0x11F5A, 0x11F5A }, /* KAWI SIGN NUKTA */ + { 0x13430, 0x13440 }, /* EGYPTIAN HIEROGLYPH VERTICAL JOINER - EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY */ + { 0x13447, 0x13455 }, /* EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START - EGYPTIAN HIEROGLYPH MODIFIER DAMAGED */ + { 0x1611E, 0x1612F }, /* GURUNG KHEMA VOWEL SIGN AA - GURUNG KHEMA SIGN THOLHOMA */ + { 0x16AF0, 0x16AF4 }, /* BASSA VAH COMBINING HIGH TONE - BASSA VAH COMBINING HIGH-LOW TONE */ + { 0x16B30, 0x16B36 }, /* PAHAWH HMONG MARK CIM TUB - PAHAWH HMONG MARK CIM TAUM */ + { 0x16F4F, 0x16F4F }, /* MIAO SIGN CONSONANT MODIFIER BAR */ + { 0x16F51, 0x16F87 }, /* MIAO SIGN ASPIRATION - MIAO VOWEL SIGN UI */ + { 0x16F8F, 0x16F92 }, /* MIAO TONE RIGHT - MIAO TONE BELOW */ + { 0x16FE4, 0x16FE4 }, /* KHITAN SMALL SCRIPT FILLER */ + { 0x16FF0, 0x16FF1 }, /* VIETNAMESE ALTERNATE READING MARK CA - VIETNAMESE ALTERNATE READING MARK NHAY */ + { 0x1BC9D, 0x1BC9E }, /* DUPLOYAN THICK LETTER SELECTOR - DUPLOYAN DOUBLE MARK */ + { 0x1BCA0, 0x1BCA3 }, /* SHORTHAND FORMAT LETTER OVERLAP - SHORTHAND FORMAT UP STEP */ + { 0x1CF00, 0x1CF2D }, /* ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT - ZNAMENNY COMBINING MARK KRYZH ON LEFT */ + { 0x1CF30, 0x1CF46 }, /* ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO - ZNAMENNY PRIZNAK MODIFIER ROG */ + { 0x1D165, 0x1D169 }, /* MUSICAL SYMBOL COMBINING STEM - MUSICAL SYMBOL COMBINING TREMOLO-3 */ + { 0x1D16D, 0x1D182 }, /* MUSICAL SYMBOL COMBINING AUGMENTATION DOT - MUSICAL SYMBOL COMBINING LOURE */ + { 0x1D185, 0x1D18B }, /* MUSICAL SYMBOL COMBINING DOIT - MUSICAL SYMBOL COMBINING TRIPLE TONGUE */ + { 0x1D1AA, 0x1D1AD }, /* MUSICAL SYMBOL COMBINING DOWN BOW - MUSICAL SYMBOL COMBINING SNAP PIZZICATO */ + { 0x1D242, 0x1D244 }, /* COMBINING GREEK MUSICAL TRISEME - COMBINING GREEK MUSICAL PENTASEME */ + { 0x1DA00, 0x1DA36 }, /* SIGNWRITING HEAD RIM - SIGNWRITING AIR SUCKING IN */ + { 0x1DA3B, 0x1DA6C }, /* SIGNWRITING MOUTH CLOSED NEUTRAL - SIGNWRITING EXCITEMENT */ + { 0x1DA75, 0x1DA75 }, /* SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS */ + { 0x1DA84, 0x1DA84 }, /* SIGNWRITING LOCATION HEAD NECK */ + { 0x1DA9B, 0x1DA9F }, /* SIGNWRITING FILL MODIFIER-2 - SIGNWRITING FILL MODIFIER-6 */ + { 0x1DAA1, 0x1DAAF }, /* SIGNWRITING ROTATION MODIFIER-2 - SIGNWRITING ROTATION MODIFIER-16 */ + { 0x1E000, 0x1E006 }, /* COMBINING GLAGOLITIC LETTER AZU - COMBINING GLAGOLITIC LETTER ZHIVETE */ + { 0x1E008, 0x1E018 }, /* COMBINING GLAGOLITIC LETTER ZEMLJA - COMBINING GLAGOLITIC LETTER HERU */ + { 0x1E01B, 0x1E021 }, /* COMBINING GLAGOLITIC LETTER SHTA - COMBINING GLAGOLITIC LETTER YATI */ + { 0x1E023, 0x1E024 }, /* COMBINING GLAGOLITIC LETTER YU - COMBINING GLAGOLITIC LETTER SMALL YUS */ + { 0x1E026, 0x1E02A }, /* COMBINING GLAGOLITIC LETTER YO - COMBINING GLAGOLITIC LETTER FITA */ + { 0x1E08F, 0x1E08F }, /* COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x1E130, 0x1E136 }, /* NYIAKENG PUACHUE HMONG TONE-B - NYIAKENG PUACHUE HMONG TONE-D */ + { 0x1E2AE, 0x1E2AE }, /* TOTO SIGN RISING TONE */ + { 0x1E2EC, 0x1E2EF }, /* WANCHO TONE TUP - WANCHO TONE KOINI */ + { 0x1E4EC, 0x1E4EF }, /* NAG MUNDARI SIGN MUHOR - NAG MUNDARI SIGN SUTUH */ + { 0x1E5EE, 0x1E5EF }, /* OL ONAL SIGN MU - OL ONAL SIGN IKIR */ + { 0x1E8D0, 0x1E8D6 }, /* MENDE KIKAKUI COMBINING NUMBER TEENS - MENDE KIKAKUI COMBINING NUMBER MILLIONS */ + { 0x1E944, 0x1E94A }, /* ADLAM ALIF LENGTHENER - ADLAM NUKTA */ + { 0x1F3FB, 0x1F3FF }, /* EMOJI MODIFIER FITZPATRICK TYPE-1-2 - EMOJI MODIFIER FITZPATRICK TYPE-6 */ + { 0x1F9B0, 0x1F9B3 }, /* EMOJI COMPONENT RED HAIR - EMOJI COMPONENT WHITE HAIR */ + { 0xE0001, 0xE0001 }, /* LANGUAGE TAG */ + { 0xE0020, 0xE007F }, /* TAG SPACE - CANCEL TAG */ + { 0xE0100, 0xE01EF }, /* VARIATION SELECTOR-17 - VARIATION SELECTOR-256 */ +}; + +/* Double-width character ranges (BMP - Basic Multilingual Plane, U+0000 to U+FFFF) */ +static const struct ucs_interval16 ucs_double_width_bmp_ranges[] = { + { 0x1100, 0x115F }, /* HANGUL CHOSEONG KIYEOK - HANGUL CHOSEONG FILLER */ + { 0x231A, 0x231B }, /* WATCH - HOURGLASS */ + { 0x2329, 0x232A }, /* LEFT-POINTING ANGLE BRACKET - RIGHT-POINTING ANGLE BRACKET */ + { 0x23E9, 0x23EC }, /* BLACK RIGHT-POINTING DOUBLE TRIANGLE - BLACK DOWN-POINTING DOUBLE TRIANGLE */ + { 0x23F0, 0x23F0 }, /* ALARM CLOCK */ + { 0x23F3, 0x23F3 }, /* HOURGLASS WITH FLOWING SAND */ + { 0x25FD, 0x25FE }, /* WHITE MEDIUM SMALL SQUARE - BLACK MEDIUM SMALL SQUARE */ + { 0x2614, 0x2615 }, /* UMBRELLA WITH RAIN DROPS - HOT BEVERAGE */ + { 0x2630, 0x2637 }, /* TRIGRAM FOR HEAVEN - TRIGRAM FOR EARTH */ + { 0x2648, 0x2653 }, /* ARIES - PISCES */ + { 0x267F, 0x267F }, /* WHEELCHAIR SYMBOL */ + { 0x268A, 0x268F }, /* MONOGRAM FOR YANG - DIGRAM FOR GREATER YIN */ + { 0x2693, 0x2693 }, /* ANCHOR */ + { 0x26A1, 0x26A1 }, /* HIGH VOLTAGE SIGN */ + { 0x26AA, 0x26AB }, /* MEDIUM WHITE CIRCLE - MEDIUM BLACK CIRCLE */ + { 0x26BD, 0x26BE }, /* SOCCER BALL - BASEBALL */ + { 0x26C4, 0x26C5 }, /* SNOWMAN WITHOUT SNOW - SUN BEHIND CLOUD */ + { 0x26CE, 0x26CE }, /* OPHIUCHUS */ + { 0x26D4, 0x26D4 }, /* NO ENTRY */ + { 0x26EA, 0x26EA }, /* CHURCH */ + { 0x26F2, 0x26F3 }, /* FOUNTAIN - FLAG IN HOLE */ + { 0x26F5, 0x26F5 }, /* SAILBOAT */ + { 0x26FA, 0x26FA }, /* TENT */ + { 0x26FD, 0x26FD }, /* FUEL PUMP */ + { 0x2705, 0x2705 }, /* WHITE HEAVY CHECK MARK */ + { 0x270A, 0x270B }, /* RAISED FIST - RAISED HAND */ + { 0x2728, 0x2728 }, /* SPARKLES */ + { 0x274C, 0x274C }, /* CROSS MARK */ + { 0x274E, 0x274E }, /* NEGATIVE SQUARED CROSS MARK */ + { 0x2753, 0x2755 }, /* BLACK QUESTION MARK ORNAMENT - WHITE EXCLAMATION MARK ORNAMENT */ + { 0x2757, 0x2757 }, /* HEAVY EXCLAMATION MARK SYMBOL */ + { 0x2795, 0x2797 }, /* HEAVY PLUS SIGN - HEAVY DIVISION SIGN */ + { 0x27B0, 0x27B0 }, /* CURLY LOOP */ + { 0x27BF, 0x27BF }, /* DOUBLE CURLY LOOP */ + { 0x2B1B, 0x2B1C }, /* BLACK LARGE SQUARE - WHITE LARGE SQUARE */ + { 0x2B50, 0x2B50 }, /* WHITE MEDIUM STAR */ + { 0x2B55, 0x2B55 }, /* HEAVY LARGE CIRCLE */ + { 0x2E80, 0x2E99 }, /* CJK RADICAL REPEAT - CJK RADICAL RAP */ + { 0x2E9B, 0x2EF3 }, /* CJK RADICAL CHOKE - CJK RADICAL C-SIMPLIFIED TURTLE */ + { 0x2F00, 0x2FD5 }, /* KANGXI RADICAL ONE - KANGXI RADICAL FLUTE */ + { 0x2FF0, 0x3029 }, /* IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT - HANGZHOU NUMERAL NINE */ + { 0x3030, 0x303E }, /* WAVY DASH - IDEOGRAPHIC VARIATION INDICATOR */ + { 0x3041, 0x3096 }, /* HIRAGANA LETTER SMALL A - HIRAGANA LETTER SMALL KE */ + { 0x309B, 0x30FF }, /* KATAKANA-HIRAGANA VOICED SOUND MARK - KATAKANA DIGRAPH KOTO */ + { 0x3105, 0x312F }, /* BOPOMOFO LETTER B - BOPOMOFO LETTER NN */ + { 0x3131, 0x318E }, /* HANGUL LETTER KIYEOK - HANGUL LETTER ARAEAE */ + { 0x3190, 0x31E5 }, /* IDEOGRAPHIC ANNOTATION LINKING MARK - CJK STROKE SZP */ + { 0x31EF, 0x321E }, /* IDEOGRAPHIC DESCRIPTION CHARACTER SUBTRACTION - PARENTHESIZED KOREAN CHARACTER O HU */ + { 0x3220, 0x3247 }, /* PARENTHESIZED IDEOGRAPH ONE - CIRCLED IDEOGRAPH KOTO */ + { 0x3250, 0xA48C }, /* PARTNERSHIP SIGN - YI SYLLABLE YYR */ + { 0xA490, 0xA4C6 }, /* YI RADICAL QOT - YI RADICAL KE */ + { 0xA960, 0xA97C }, /* HANGUL CHOSEONG TIKEUT-MIEUM - HANGUL CHOSEONG SSANGYEORINHIEUH */ + { 0xAC00, 0xD7A3 }, /* HANGUL SYLLABLE GA - HANGUL SYLLABLE HIH */ + { 0xF900, 0xFAFF }, /* U+F900 - U+FAFF */ + { 0xFE10, 0xFE19 }, /* PRESENTATION FORM FOR VERTICAL COMMA - PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS */ + { 0xFE30, 0xFE52 }, /* PRESENTATION FORM FOR VERTICAL TWO DOT LEADER - SMALL FULL STOP */ + { 0xFE54, 0xFE66 }, /* SMALL SEMICOLON - SMALL EQUALS SIGN */ + { 0xFE68, 0xFE6B }, /* SMALL REVERSE SOLIDUS - SMALL COMMERCIAL AT */ + { 0xFF01, 0xFF60 }, /* FULLWIDTH EXCLAMATION MARK - FULLWIDTH RIGHT WHITE PARENTHESIS */ + { 0xFFE0, 0xFFE6 }, /* FULLWIDTH CENT SIGN - FULLWIDTH WON SIGN */ +}; + +/* Double-width character ranges (non-BMP, U+10000 and above) */ +static const struct ucs_interval32 ucs_double_width_non_bmp_ranges[] = { + { 0x16FE0, 0x16FE3 }, /* TANGUT ITERATION MARK - OLD CHINESE ITERATION MARK */ + { 0x17000, 0x187F7 }, /* U+17000 - U+187F7 */ + { 0x18800, 0x18CD5 }, /* TANGUT COMPONENT-001 - KHITAN SMALL SCRIPT CHARACTER-18CD5 */ + { 0x18CFF, 0x18D08 }, /* U+18CFF - U+18D08 */ + { 0x1AFF0, 0x1AFF3 }, /* KATAKANA LETTER MINNAN TONE-2 - KATAKANA LETTER MINNAN TONE-5 */ + { 0x1AFF5, 0x1AFFB }, /* KATAKANA LETTER MINNAN TONE-7 - KATAKANA LETTER MINNAN NASALIZED TONE-5 */ + { 0x1AFFD, 0x1AFFE }, /* KATAKANA LETTER MINNAN NASALIZED TONE-7 - KATAKANA LETTER MINNAN NASALIZED TONE-8 */ + { 0x1B000, 0x1B122 }, /* KATAKANA LETTER ARCHAIC E - KATAKANA LETTER ARCHAIC WU */ + { 0x1B132, 0x1B132 }, /* HIRAGANA LETTER SMALL KO */ + { 0x1B150, 0x1B152 }, /* HIRAGANA LETTER SMALL WI - HIRAGANA LETTER SMALL WO */ + { 0x1B155, 0x1B155 }, /* KATAKANA LETTER SMALL KO */ + { 0x1B164, 0x1B167 }, /* KATAKANA LETTER SMALL WI - KATAKANA LETTER SMALL N */ + { 0x1B170, 0x1B2FB }, /* NUSHU CHARACTER-1B170 - NUSHU CHARACTER-1B2FB */ + { 0x1D300, 0x1D356 }, /* MONOGRAM FOR EARTH - TETRAGRAM FOR FOSTERING */ + { 0x1D360, 0x1D376 }, /* COUNTING ROD UNIT DIGIT ONE - IDEOGRAPHIC TALLY MARK FIVE */ + { 0x1F000, 0x1F02F }, /* U+1F000 - U+1F02F */ + { 0x1F0A0, 0x1F0FF }, /* U+1F0A0 - U+1F0FF */ + { 0x1F18E, 0x1F18E }, /* NEGATIVE SQUARED AB */ + { 0x1F191, 0x1F19A }, /* SQUARED CL - SQUARED VS */ + { 0x1F200, 0x1F202 }, /* SQUARE HIRAGANA HOKA - SQUARED KATAKANA SA */ + { 0x1F210, 0x1F23B }, /* SQUARED CJK UNIFIED IDEOGRAPH-624B - SQUARED CJK UNIFIED IDEOGRAPH-914D */ + { 0x1F240, 0x1F248 }, /* TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C - TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557 */ + { 0x1F250, 0x1F251 }, /* CIRCLED IDEOGRAPH ADVANTAGE - CIRCLED IDEOGRAPH ACCEPT */ + { 0x1F260, 0x1F265 }, /* ROUNDED SYMBOL FOR FU - ROUNDED SYMBOL FOR CAI */ + { 0x1F300, 0x1F3FA }, /* CYCLONE - AMPHORA */ + { 0x1F400, 0x1F64F }, /* RAT - PERSON WITH FOLDED HANDS */ + { 0x1F680, 0x1F9AF }, /* ROCKET - PROBING CANE */ + { 0x1F9B4, 0x1FAFF }, /* U+1F9B4 - U+1FAFF */ + { 0x20000, 0x2FFFD }, /* U+20000 - U+2FFFD */ + { 0x30000, 0x3FFFD }, /* U+30000 - U+3FFFD */ +}; diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index f5642b3038e4..ed39d9cb4432 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -104,7 +104,6 @@ #include <linux/uaccess.h> #include <linux/kdb.h> #include <linux/ctype.h> -#include <linux/bsearch.h> #include <linux/gcd.h> #define MAX_NR_CON_DRIVER 16 @@ -444,6 +443,15 @@ static void vc_uniscr_scroll(struct vc_data *vc, unsigned int top, } } +static u32 vc_uniscr_getc(struct vc_data *vc, int relative_pos) +{ + int pos = vc->state.x + vc->vc_need_wrap + relative_pos; + + if (vc->vc_uni_lines && in_range(pos, 0, vc->vc_cols)) + return vc->vc_uni_lines[vc->state.y][pos]; + return 0; +} + static void vc_uniscr_copy_area(u32 **dst_lines, unsigned int dst_cols, unsigned int dst_rows, @@ -1862,6 +1870,14 @@ int mouse_reporting(void) return vc_cons[fg_console].d->vc_report_mouse; } +/* invoked via ioctl(TIOCLINUX) */ +static int get_bracketed_paste(struct tty_struct *tty) +{ + struct vc_data *vc = tty->driver_data; + + return vc->vc_bracketed_paste; +} + enum { CSI_DEC_hl_CURSOR_KEYS = 1, /* CKM: cursor keys send ^[Ox/^[[x */ CSI_DEC_hl_132_COLUMNS = 3, /* COLM: 80/132 mode switch */ @@ -1872,6 +1888,7 @@ enum { CSI_DEC_hl_MOUSE_X10 = 9, CSI_DEC_hl_SHOW_CURSOR = 25, /* TCEM */ CSI_DEC_hl_MOUSE_VT200 = 1000, + CSI_DEC_hl_BRACKETED_PASTE = 2004, }; /* console_lock is held */ @@ -1924,6 +1941,9 @@ static void csi_DEC_hl(struct vc_data *vc, bool on_off) case CSI_DEC_hl_MOUSE_VT200: vc->vc_report_mouse = on_off ? 2 : 0; break; + case CSI_DEC_hl_BRACKETED_PASTE: + vc->vc_bracketed_paste = on_off; + break; } } @@ -2149,6 +2169,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear) vc->state.charset = 0; vc->vc_need_wrap = 0; vc->vc_report_mouse = 0; + vc->vc_bracketed_paste = 0; vc->vc_utf = default_utf8; vc->vc_utf_count = 0; @@ -2712,43 +2733,6 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c) } } -/* is_double_width() is based on the wcwidth() implementation by - * Markus Kuhn -- 2007-05-26 (Unicode 5.0) - * Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c - */ -struct interval { - uint32_t first; - uint32_t last; -}; - -static int ucs_cmp(const void *key, const void *elt) -{ - uint32_t ucs = *(uint32_t *)key; - struct interval e = *(struct interval *) elt; - - if (ucs > e.last) - return 1; - else if (ucs < e.first) - return -1; - return 0; -} - -static int is_double_width(uint32_t ucs) -{ - static const struct interval double_width[] = { - { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E }, - { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF }, - { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 }, - { 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD } - }; - if (ucs < double_width[0].first || - ucs > double_width[ARRAY_SIZE(double_width) - 1].last) - return 0; - - return bsearch(&ucs, double_width, ARRAY_SIZE(double_width), - sizeof(struct interval), ucs_cmp) != NULL; -} - struct vc_draw_region { unsigned long from, to; int x; @@ -2817,7 +2801,7 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan) if ((c & 0xc0) == 0x80) { /* Unexpected continuation byte? */ if (!vc->vc_utf_count) - return 0xfffd; + goto bad_sequence; vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); vc->vc_npar++; @@ -2829,17 +2813,17 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan) /* Reject overlong sequences */ if (c <= utf8_length_changes[vc->vc_npar - 1] || c > utf8_length_changes[vc->vc_npar]) - return 0xfffd; + goto bad_sequence; return vc_sanitize_unicode(c); } /* Single ASCII byte or first byte of a sequence received */ if (vc->vc_utf_count) { - /* Continuation byte expected */ + /* A continuation byte was expected */ *rescan = true; vc->vc_utf_count = 0; - return 0xfffd; + goto bad_sequence; } /* Nothing to do if an ASCII byte was received */ @@ -2858,11 +2842,14 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan) vc->vc_utf_count = 3; vc->vc_utf_char = (c & 0x07); } else { - return 0xfffd; + goto bad_sequence; } need_more_bytes: return -1; + +bad_sequence: + return 0xfffd; } static int vc_translate(struct vc_data *vc, int *c, bool *rescan) @@ -2940,54 +2927,143 @@ static bool vc_is_control(struct vc_data *vc, int tc, int c) return false; } +static void vc_con_rewind(struct vc_data *vc) +{ + if (vc->state.x && !vc->vc_need_wrap) { + vc->vc_pos -= 2; + vc->state.x--; + } + vc->vc_need_wrap = 0; +} + +#define UCS_ZWS 0x200b /* Zero Width Space */ +#define UCS_VS16 0xfe0f /* Variation Selector 16 */ +#define UCS_REPLACEMENT 0xfffd /* Replacement Character */ + +static int vc_process_ucs(struct vc_data *vc, int *c, int *tc) +{ + u32 prev_c, curr_c = *c; + + if (ucs_is_double_width(curr_c)) { + /* + * The Unicode screen memory is allocated only when + * required. This is one such case as we need to remember + * which displayed characters are double-width. + */ + vc_uniscr_check(vc); + return 2; + } + + if (!ucs_is_zero_width(curr_c)) + return 1; + + /* From here curr_c is known to be zero-width. */ + + if (ucs_is_double_width(vc_uniscr_getc(vc, -2))) { + /* + * Let's merge this zero-width code point with the preceding + * double-width code point by replacing the existing + * zero-width space padding. To do so we rewind one column + * and pretend this has a width of 1. + * We give the legacy display the same initial space padding. + */ + vc_con_rewind(vc); + *tc = ' '; + return 1; + } + + /* From here the preceding character, if any, must be single-width. */ + prev_c = vc_uniscr_getc(vc, -1); + + if (curr_c == UCS_VS16 && prev_c != 0) { + /* + * VS16 (U+FE0F) is special. It typically turns the preceding + * single-width character into a double-width one. Let it + * have a width of 1 effectively making the combination with + * the preceding character double-width. + */ + *tc = ' '; + return 1; + } + + /* try recomposition */ + prev_c = ucs_recompose(prev_c, curr_c); + if (prev_c != 0) { + vc_con_rewind(vc); + *tc = *c = prev_c; + return 1; + } + + /* Otherwise zero-width code points are ignored. */ + return 0; +} + +static int vc_get_glyph(struct vc_data *vc, int tc) +{ + int glyph = conv_uni_to_pc(vc, tc); + u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; + + if (!(glyph & ~charmask)) + return glyph; + + if (glyph == -1) + return -1; /* nothing to display */ + + /* Glyph not found */ + if ((!vc->vc_utf || vc->vc_disp_ctrl || tc < 128) && !(tc & ~charmask)) { + /* + * In legacy mode use the glyph we get by a 1:1 mapping. + * This would make absolutely no sense with Unicode in mind, but do this for + * ASCII characters since a font may lack Unicode mapping info and we don't + * want to end up with having question marks only. + */ + return tc; + } + + /* + * The Unicode screen memory is allocated only when required. + * This is one such case: we're about to "cheat" with the displayed + * character meaning the simple screen buffer won't hold the original + * information, whereas the Unicode screen buffer always does. + */ + vc_uniscr_check(vc); + + /* Try getting a simpler fallback character. */ + tc = ucs_get_fallback(tc); + if (tc) + return vc_get_glyph(vc, tc); + + /* Display U+FFFD (Unicode Replacement Character). */ + return conv_uni_to_pc(vc, UCS_REPLACEMENT); +} + static int vc_con_write_normal(struct vc_data *vc, int tc, int c, struct vc_draw_region *draw) { int next_c; unsigned char vc_attr = vc->vc_attr; - u16 himask = vc->vc_hi_font_mask, charmask = himask ? 0x1ff : 0xff; + u16 himask = vc->vc_hi_font_mask; u8 width = 1; bool inverse = false; if (vc->vc_utf && !vc->vc_disp_ctrl) { - if (is_double_width(c)) - width = 2; + width = vc_process_ucs(vc, &c, &tc); + if (!width) + goto out; } /* Now try to find out how to display it */ - tc = conv_uni_to_pc(vc, tc); - if (tc & ~charmask) { - if (tc == -1 || tc == -2) - return -1; /* nothing to display */ - - /* Glyph not found */ - if ((!vc->vc_utf || vc->vc_disp_ctrl || c < 128) && - !(c & ~charmask)) { - /* - * In legacy mode use the glyph we get by a 1:1 - * mapping. - * This would make absolutely no sense with Unicode in - * mind, but do this for ASCII characters since a font - * may lack Unicode mapping info and we don't want to - * end up with having question marks only. - */ - tc = c; - } else { - /* - * Display U+FFFD. If it's not found, display an inverse - * question mark. - */ - tc = conv_uni_to_pc(vc, 0xfffd); - if (tc < 0) { - inverse = true; - tc = conv_uni_to_pc(vc, '?'); - if (tc < 0) - tc = '?'; - - vc_attr = vc_invert_attr(vc); - con_flush(vc, draw); - } - } + tc = vc_get_glyph(vc, tc); + if (tc == -1) + return -1; /* nothing to display */ + if (tc < 0) { + inverse = true; + tc = conv_uni_to_pc(vc, '?'); + if (tc < 0) + tc = '?'; + + vc_attr = vc_invert_attr(vc); + con_flush(vc, draw); } next_c = c; @@ -3028,8 +3104,14 @@ static int vc_con_write_normal(struct vc_data *vc, int tc, int c, tc = conv_uni_to_pc(vc, ' '); if (tc < 0) tc = ' '; - next_c = ' '; + /* + * Store a zero-width space in the Unicode screen given that + * the previous code point is semantically double width. + */ + next_c = UCS_ZWS; } + +out: notify_write(vc, c); if (inverse) @@ -3414,6 +3496,8 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) break; case TIOCL_BLANKEDSCREEN: return console_blanked; + case TIOCL_GETBRACKETEDPASTE: + return get_bracketed_paste(tty); default: return -EINVAL; } diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c index 4b91072f3a4e..61342e06970a 100644 --- a/drivers/tty/vt/vt_ioctl.c +++ b/drivers/tty/vt/vt_ioctl.c @@ -951,6 +951,22 @@ int vt_ioctl(struct tty_struct *tty, (unsigned short __user *)arg); case VT_WAITEVENT: return vt_event_wait_ioctl((struct vt_event __user *)arg); + + case VT_GETCONSIZECSRPOS: + { + struct vt_consizecsrpos concsr; + + console_lock(); + concsr.con_cols = vc->vc_cols; + concsr.con_rows = vc->vc_rows; + concsr.csr_col = vc->state.x; + concsr.csr_row = vc->state.y; + console_unlock(); + if (copy_to_user(up, &concsr, sizeof(concsr))) + return -EFAULT; + return 0; + } + default: return -ENOIOCTLCMD; } @@ -1103,8 +1119,6 @@ long vt_compat_ioctl(struct tty_struct *tty, case VT_WAITACTIVE: case VT_RELDISP: case VT_DISALLOCATE: - case VT_RESIZE: - case VT_RESIZEX: return vt_ioctl(tty, cmd, arg); /* |